From e2b5a7d9eb5f086bd6d1de9a927819de7a3ca7c1 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Thu, 5 Oct 2023 00:59:22 +0200 Subject: [PATCH 01/50] some functions for tff --- .../java/de/uka/ilkd/key/gui/Example.java | 196 +++++++++++++++ .../de/uka/ilkd/key/gui/ExampleChooser.java | 179 -------------- keyext.api/build.gradle | 6 + .../org/keyproject/key/FileTypeAdapter.java | 20 ++ .../org/keyproject/key/remoteapi/KeyApi.java | 58 +++++ .../keyproject/key/remoteapi/KeyApiImpl.java | 56 +++++ .../key/remoteapi/KeyExampleApi.java | 14 ++ .../keyproject/key/remoteapi/KeyMetaApi.java | 21 ++ .../key/remoteapi/MacroDescription.java | 9 + .../org/keyproject/key/remoteapi/Main.java | 63 +++++ .../org/keyproject/key/remoteapi/ProofId.java | 4 + .../key/remoteapi/ProofLoading.java | 67 ++++++ .../keyproject/key/remoteapi/TraceValue.java | 5 + .../keyproject/key/remoteclient/Client.java | 53 +++++ .../key/remoteclient/ClientApi.java | 224 ++++++++++++++++++ .../key/remoteclient/SimpleClient.java | 9 + settings.gradle | 2 + 17 files changed, 807 insertions(+), 179 deletions(-) create mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java create mode 100644 keyext.api/build.gradle create mode 100644 keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java new file mode 100644 index 00000000000..85a85b65df1 --- /dev/null +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java @@ -0,0 +1,196 @@ +package de.uka.ilkd.key.gui; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; + +/** + * This class wraps a {@link java.io.File} and has a special {@link #toString()} method only using the + * short file name w/o path. + *

+ * Used for displaying files in the examples list w/o prefix + */ +public class Example { + private static final Logger LOGGER = LoggerFactory.getLogger(Example.class); + /** + * This constant is accessed by the eclipse based projects. + */ + public static final String KEY_FILE_NAME = "project.key"; + + private static final String PROOF_FILE_NAME = "project.proof"; + + /** + * The default category under which examples range if they do not have {@link #KEY_PATH} + * set. + */ + public static final String DEFAULT_CATEGORY_PATH = "Unsorted"; + + /** + * The {@link Properties} key to specify the path in the tree. + */ + public static final String KEY_PATH = "example.path"; + + /** + * The {@link Properties} key to specify the name of the example. Directory name if left + * open. + */ + public static final String KEY_NAME = "example.name"; + + /** + * The {@link Properties} key to specify the file for the example. KEY_FILE_NAME by default + */ + public static final String KEY_FILE = "example.file"; + + /** + * The {@link Properties} key to specify the proof file in the tree. May be left open + */ + public static final String KEY_PROOF_FILE = "example.proofFile"; + + /** + * The {@link Properties} key to specify the path in the tree. Prefix to specify additional + * files to load. Append 1, 2, 3, ... + */ + public static final String ADDITIONAL_FILE_PREFIX = "example.additionalFile."; + + /** + * The {@link Properties} key to specify the path in the tree. Prefix to specify export + * files which are not shown as tabs in the example wizard but are extracted to Java + * projects in the Eclipse integration. Append 1, 2, 3, ... + */ + public static final String EXPORT_FILE_PREFIX = "example.exportFile."; + + public final File exampleFile; + public final File directory; + public final String description; + public final Properties properties; + + public Example(File file) throws IOException { + this.exampleFile = file; + this.directory = file.getParentFile(); + this.properties = new Properties(); + StringBuilder sb = new StringBuilder(); + extractDescription(file, sb, properties); + this.description = sb.toString(); + } + + public File getDirectory() { + return directory; + } + + public File getProofFile() { + return new File(directory, properties.getProperty(KEY_PROOF_FILE, PROOF_FILE_NAME)); + } + + public File getObligationFile() { + return new File(directory, properties.getProperty(KEY_FILE, KEY_FILE_NAME)); + } + + public String getName() { + return properties.getProperty(KEY_NAME, directory.getName()); + } + + public String getDescription() { + return description; + } + + public File getExampleFile() { + return exampleFile; + } + + public List getAdditionalFiles() { + var result = new ArrayList(); + int i = 1; + while (properties.containsKey(ADDITIONAL_FILE_PREFIX + i)) { + result.add(new File(directory, properties.getProperty(ADDITIONAL_FILE_PREFIX + i))); + i++; + } + return result; + } + + public List getExportFiles() { + ArrayList result = new ArrayList<>(); + int i = 1; + while (properties.containsKey(EXPORT_FILE_PREFIX + i)) { + result.add(new File(directory, properties.getProperty(EXPORT_FILE_PREFIX + i))); + i++; + } + return result; + } + + public String[] getPath() { + return properties.getProperty(KEY_PATH, DEFAULT_CATEGORY_PATH).split("/"); + } + + @Override + public String toString() { + return getName(); + } + + public void addToTreeModel(DefaultTreeModel model) { + DefaultMutableTreeNode node = + findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); + node.add(new DefaultMutableTreeNode(this)); + } + + private DefaultMutableTreeNode findChild(DefaultMutableTreeNode root, String[] path, + int from) { + if (from == path.length) { + return root; + } + Enumeration en = root.children(); + while (en.hasMoreElements()) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) en.nextElement(); + if (node.getUserObject().equals(path[from])) { + return findChild(node, path, from + 1); + } + } + // not found ==> add new + DefaultMutableTreeNode node = new DefaultMutableTreeNode(path[from]); + root.add(node); + return findChild(node, path, from + 1); + } + + public boolean hasProof() { + return properties.containsKey(KEY_PROOF_FILE); + } + + private static StringBuilder extractDescription(File file, StringBuilder sb, + Properties properties) { + try (BufferedReader r = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) { + String line; + boolean emptyLineSeen = false; + while ((line = r.readLine()) != null) { + if (emptyLineSeen) { + sb.append(line).append("\n"); + } else { + String trimmed = line.trim(); + if (trimmed.length() == 0) { + emptyLineSeen = true; + } else if (trimmed.startsWith("#")) { + // ignore + } else { + String[] entry = trimmed.split(" *[:=] *", 2); + if (entry.length > 1) { + properties.put(entry[0], entry[1]); + } + } + } + } + } catch (IOException e) { + LOGGER.error("", e); + return sb; + } + return sb; + } +} \ No newline at end of file diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java index f4ee4884408..e37603b344e 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java @@ -37,15 +37,6 @@ public final class ExampleChooser extends JDialog { */ public static final String EXAMPLES_PATH = "examples"; - private static final long serialVersionUID = -4405666868752394532L; - - /** - * This constant is accessed by the eclipse based projects. - */ - public static final String KEY_FILE_NAME = "project.key"; - - private static final String PROOF_FILE_NAME = "project.proof"; - /** * Java property name to specify a custom key example folder. */ @@ -75,149 +66,7 @@ public final class ExampleChooser extends JDialog { */ private Example selectedExample; - /** - * This class wraps a {@link File} and has a special {@link #toString()} method only using the - * short file name w/o path. - *

- * Used for displaying files in the examples list w/o prefix - */ - public static class Example { - /** - * The default category under which examples range if they do not have {@link #KEY_PATH} - * set. - */ - private static final String DEFAULT_CATEGORY_PATH = "Unsorted"; - - /** - * The {@link Properties} key to specify the path in the tree. - */ - private static final String KEY_PATH = "example.path"; - - /** - * The {@link Properties} key to specify the name of the example. Directory name if left - * open. - */ - private static final String KEY_NAME = "example.name"; - - /** - * The {@link Properties} key to specify the file for the example. KEY_FILE_NAME by default - */ - private static final String KEY_FILE = "example.file"; - - /** - * The {@link Properties} key to specify the proof file in the tree. May be left open - */ - private static final String KEY_PROOF_FILE = "example.proofFile"; - - /** - * The {@link Properties} key to specify the path in the tree. Prefix to specify additional - * files to load. Append 1, 2, 3, ... - */ - private static final String ADDITIONAL_FILE_PREFIX = "example.additionalFile."; - - /** - * The {@link Properties} key to specify the path in the tree. Prefix to specify export - * files which are not shown as tabs in the example wizard but are extracted to Java - * projects in the Eclipse integration. Append 1, 2, 3, ... - */ - private static final String EXPORT_FILE_PREFIX = "example.exportFile."; - - private final File exampleFile; - private final File directory; - private final String description; - private final Properties properties; - - public Example(File file) throws IOException { - this.exampleFile = file; - this.directory = file.getParentFile(); - this.properties = new Properties(); - StringBuilder sb = new StringBuilder(); - extractDescription(file, sb, properties); - this.description = sb.toString(); - } - - public File getDirectory() { - return directory; - } - public File getProofFile() { - return new File(directory, properties.getProperty(KEY_PROOF_FILE, PROOF_FILE_NAME)); - } - - public File getObligationFile() { - return new File(directory, properties.getProperty(KEY_FILE, KEY_FILE_NAME)); - } - - public String getName() { - return properties.getProperty(KEY_NAME, directory.getName()); - } - - public String getDescription() { - return description; - } - - public File getExampleFile() { - return exampleFile; - } - - public List getAdditionalFiles() { - ArrayList result = new ArrayList<>(); - int i = 1; - while (properties.containsKey(ADDITIONAL_FILE_PREFIX + i)) { - result.add(new File(directory, properties.getProperty(ADDITIONAL_FILE_PREFIX + i))); - i++; - } - return result; - } - - public List getExportFiles() { - ArrayList result = new ArrayList<>(); - int i = 1; - while (properties.containsKey(EXPORT_FILE_PREFIX + i)) { - result.add(new File(directory, properties.getProperty(EXPORT_FILE_PREFIX + i))); - i++; - } - return result; - } - - public String[] getPath() { - return properties.getProperty(KEY_PATH, DEFAULT_CATEGORY_PATH).split("/"); - } - - @Override - public String toString() { - return getName(); - } - - public void addToTreeModel(DefaultTreeModel model) { - DefaultMutableTreeNode node = - findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); - node.add(new DefaultMutableTreeNode(this)); - } - - private DefaultMutableTreeNode findChild(DefaultMutableTreeNode root, String[] path, - int from) { - if (from == path.length) { - return root; - } - Enumeration en = root.children(); - while (en.hasMoreElements()) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode) en.nextElement(); - if (node.getUserObject().equals(path[from])) { - return findChild(node, path, from + 1); - } - } - // not found ==> add new - DefaultMutableTreeNode node = new DefaultMutableTreeNode(path[from]); - root.add(node); - return findChild(node, path, from + 1); - } - - public boolean hasProof() { - return properties.containsKey(KEY_PROOF_FILE); - } - - } // ------------------------------------------------------------------------- // constructors @@ -352,34 +201,6 @@ private static String fileAsString(File f) { } } - private static StringBuilder extractDescription(File file, StringBuilder sb, - Properties properties) { - try (BufferedReader r = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) { - String line; - boolean emptyLineSeen = false; - while ((line = r.readLine()) != null) { - if (emptyLineSeen) { - sb.append(line).append("\n"); - } else { - String trimmed = line.trim(); - if (trimmed.length() == 0) { - emptyLineSeen = true; - } else if (trimmed.startsWith("#")) { - // ignore - } else { - String[] entry = trimmed.split(" *[:=] *", 2); - if (entry.length > 1) { - properties.put(entry[0], entry[1]); - } - } - } - } - } catch (IOException e) { - LOGGER.error("", e); - return sb; - } - return sb; - } private void updateDescription() { diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle new file mode 100644 index 00000000000..463b7dbc11a --- /dev/null +++ b/keyext.api/build.gradle @@ -0,0 +1,6 @@ +dependencies { + implementation(project(":key.core")) + implementation(project(":key.ui")) + + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java b/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java new file mode 100644 index 00000000000..67240012e90 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java @@ -0,0 +1,20 @@ +package org.keyproject.key; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.File; +import java.io.IOException; + +public class FileTypeAdapter extends TypeAdapter { + @Override + public void write(JsonWriter out, File value) throws IOException { + out.value(value.toString()); + } + + @Override + public File read(JsonReader in) throws IOException { + return new File(in.nextString()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java new file mode 100644 index 00000000000..76c2d1eefdd --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java @@ -0,0 +1,58 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.gui.Example; +import de.uka.ilkd.key.gui.ExampleChooser; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public interface KeyApi extends KeyExampleApi, KeyMetaApi { + //region general server management + /** + * Shutdown Request (:leftwards_arrow_with_hook:) + The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. + + If a server receives requests after a shutdown request those requests should error with InvalidRequest. + + Request: + + method: ‘shutdown’ + params: none + Response: + + result: null + error: code and message set in case an exception happens during shutdown request. + */ + @JsonRequest + Void shutdown(); + + /** + * Exit Notification (:arrow_right:) + * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. + *

+ * Notification: + *

+ * method: ‘exit’ + * params: none + */ + @JsonNotification + void exit(); + + + + interface SetTraceParams { + /** + * The new value that should be assigned to the trace setting. + */ + TraceValue value = null; + } + /** + * SetTrace Notification + * A notification that should be used by the client to modify the trace setting of the server. + */ + @JsonNotification + void setTrace(SetTraceParams params); + //endregion +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java new file mode 100644 index 00000000000..0a967998dac --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java @@ -0,0 +1,56 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.api.KeYApi; +import de.uka.ilkd.key.gui.Example; +import de.uka.ilkd.key.gui.ExampleChooser; +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import de.uka.ilkd.key.util.KeYConstants; +import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@JsonSegment +class KeyApiImpl implements KeyApi { + @Override + @JsonRequest + public CompletableFuture> examples() { + return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); + } + + @Override + public Void shutdown() { + return null; + } + + @Override + public void exit() { + + } + + @Override + public void setTrace(SetTraceParams params) { + + } + + @Override + public CompletableFuture getVersion() { + return CompletableFuture.completedFuture(KeYConstants.VERSION); + } + + @Override + public CompletableFuture> getAvailableMacros() { + return CompletableFuture.completedFuture( + KeYApi.getMacroApi().getMacros().stream().map(MacroDescription::from) + .toList() + ); + } + + @Override + public CompletableFuture>> getAvailableScriptCommands() { + return CompletableFuture.completedFuture( + KeYApi.getScriptCommandApi().getScriptCommands().stream().toList()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java new file mode 100644 index 00000000000..f1fe80a6dfc --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java @@ -0,0 +1,14 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.gui.Example; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@JsonSegment("examples") +public interface KeyExampleApi { + @JsonRequest("list") + CompletableFuture> examples(); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java new file mode 100644 index 00000000000..e5538b30896 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java @@ -0,0 +1,21 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@JsonSegment("meta") +public interface KeyMetaApi { + @JsonRequest + CompletableFuture getVersion(); + + @JsonRequest + CompletableFuture> getAvailableMacros(); + + @JsonRequest + CompletableFuture>> getAvailableScriptCommands(); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java new file mode 100644 index 00000000000..2f34d3e03ed --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java @@ -0,0 +1,9 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.macros.ProofMacro; + +public record MacroDescription(String name, String description, String category) { + public static MacroDescription from(ProofMacro m) { + return new MacroDescription(m.getName(), m.getDescription(), m.getCategory()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java new file mode 100644 index 00000000000..127b36a702c --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java @@ -0,0 +1,63 @@ +package org.keyproject.key.remoteapi; + +import com.google.gson.GsonBuilder; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.keyproject.key.FileTypeAdapter; +import org.keyproject.key.remoteclient.ClientApi; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class Main { + public static void main(String[] args) throws ExecutionException, InterruptedException { + var future = launch(System.out, System.in); + future.startListening(); + } + + public static Launcher launch(OutputStream out, InputStream in) { + var localServices = getLocalServices(); + var remoteInterfaces = getRemoteInterfaces(); + var launcherBuilder = new Launcher.Builder() + .setOutput(out) + .setInput(in) + .traceMessages(new PrintWriter(System.err)) + .validateMessages(true); + + launcherBuilder.configureGson(Main::configureJson); + + //if (localServices != null && !localServices.isEmpty()) + launcherBuilder.setLocalService(new KeyApiImpl()); + //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) + launcherBuilder.setRemoteInterface(ClientApi.class); + + var launcher = launcherBuilder.create(); + return launcher; + } + + public static void configureJson(GsonBuilder gsonBuilder) { + gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); + } + + private static Collection> getRemoteInterfaces() { + return Collections.singleton(ClientApi.class); + /* return ServiceLoader.load(ClientService.class) + .stream() + .map(ServiceLoader.Provider::type) + .collect(Collectors.toSet()); + */ + } + + private static List getLocalServices() { + return Collections.singletonList(new KeyApiImpl()); + /*return ServiceLoader.load(KeyService.class) + .stream().map(ServiceLoader.Provider::get) + .map(it -> (Object) it) + .toList();*/ + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java new file mode 100644 index 00000000000..65db8662e4e --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java @@ -0,0 +1,4 @@ +package org.keyproject.key.remoteapi; + +public record ProofId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java new file mode 100644 index 00000000000..7e99ffd0cf5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java @@ -0,0 +1,67 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.api.ProofManagementApi; +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.io.File; +import java.util.List; + +@JsonSegment +public interface ProofLoading { + @JsonRequest ProofId loadExample(String id); + + interface LoadParams { + File keyFile; + File javaFile; + + List classPath, + File bootClassPath, List includes + } + + /** + * @param keyFile + * @return + * @throws ProblemLoaderException + */ + @JsonRequest ProofId loadFromKeyFile(File keyFile) throws ProblemLoaderException { + return new ProofManagementApi(KeYEnvironment.load(keyFile)); + } + + /** + * @param location + * @param classPath + * @param bootClassPath + * @param includes + * @return + * @throws ProblemLoaderException + */ + @JsonRequest ProofId loadProof(File location, List classPath, + File bootClassPath, List includes) throws ProblemLoaderException { + return new ProofManagementApi( + KeYEnvironment.load(location, classPath, bootClassPath, includes)); + } + + /** + * @param javaSourceCode + * @return + * @throws ProblemLoaderException + */ + @JsonRequest ProofId loadProof(File javaSourceCode) throws ProblemLoaderException { + return loadProof(javaSourceCode, null, null, null); + } + + /** + * Load a proof file, creates a KeY environment that can be accessed with other methods from + * this facade + * + * @param file Path to the source code folder/file or to a *.proof file + * @param classPaths Optionally: Additional specifications for API classes + * @param bootClassPath Optionally: Different default specifications for Java API + * @param includes Optionally: Additional includes to consider + */ + @JsonRequest ProofId loadProofFile(File file, List classPaths, File bootClassPath, + List includes); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java new file mode 100644 index 00000000000..1d1d4859e57 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java @@ -0,0 +1,5 @@ +package org.keyproject.key.remoteapi; + +public enum TraceValue { + Off, Message, All; +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java new file mode 100644 index 00000000000..4fd0b792189 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java @@ -0,0 +1,53 @@ +package org.keyproject.key.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; +import org.keyproject.key.remoteapi.Main; +import org.keyproject.key.remoteapi.KeyApi; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.concurrent.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Client { + public static void main(String[] args) throws IOException, ExecutionException, InterruptedException, TimeoutException { + PipedInputStream inClient = new PipedInputStream(); + PipedOutputStream outClient = new PipedOutputStream(); + PipedInputStream inServer = new PipedInputStream(); + PipedOutputStream outServer = new PipedOutputStream(); + + inClient.connect(outServer); + outClient.connect(inServer); + + Launcher serverLauncher = Main.launch(outServer, inServer); + + var client = new SimpleClient(); + Launcher clientLauncher = new Launcher.Builder() + .setLocalService(client) + .setRemoteInterfaces(Collections.singleton(KeyApi.class)) + .setInput(inClient) + .setOutput(outClient) + .configureGson(Main::configureJson) + .traceMessages(new PrintWriter(System.err)) + .create(); + + Logger logger = Logger.getLogger(StreamMessageProducer.class.getName()); + logger.setLevel(Level.SEVERE); + + var clientListening = clientLauncher.startListening(); + var serverListening = serverLauncher.startListening(); + + //clientLauncher.getRemoteProxy().examples(); + serverLauncher.getRemoteProxy().sayHello("Alex"); + + serverListening.get(1, TimeUnit.SECONDS); + clientListening.get(1, TimeUnit.SECONDS); + } +} + + diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java new file mode 100644 index 00000000000..23c3ddf9e39 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java @@ -0,0 +1,224 @@ +package org.keyproject.key.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.eclipse.lsp4j.jsonrpc.validation.NonNull; + +import javax.annotation.Nullable; + +@JsonSegment +public interface ClientApi { + @JsonNotification + void sayHello(String e); + + /** + * LogTrace Notification (:arrow_left:) + * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. + *

+ * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. + *

+ * Notification: + *

+ * method: ‘$/logTrace’ + * params: LogTraceParams defined as follows: + */ + @JsonNotification + void logTrace(LogTraceParams params); + + interface LogTraceParams { + /** + * The message to be logged. + */ + @NonNull + String message = null; + /** + * Additional information that can be computed if the `trace` configuration + * is set to `'verbose'` + */ + String verbose = null; + } + + //region Window + + /** + * ShowMessage Notification (:arrow_left:) + * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. + *

+ * Notification: + *

+ * method: ‘window/showMessage’ + * params: ShowMessageParams defined as follows: + */ + @JsonNotification + public void ShowMessage(ShowMessageParams params); + + interface ShowMessageParams { + /** + * The message type. See {@link MessageType}. + */ + MessageType type = null; + + /** + * The actual message. + */ + String message = null; + } + + enum MessageType { + + Unused, + /** + * An error message. + */ + Error, + /** + * A warning message. + */ + Warning, + /** + * An information message. + */ + Info, + /** + * A log message. + */ + Log, + /** + * A debug message. + * + * @proposed + * @since 3.18.0 + */ + Debug + } + + /** + * ShowMessage Request (:arrow_right_hook:) + * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. + */ + @JsonRequest + @Nullable + MessageActionItem ShowMessage(ShowMessageRequestParams params); + + interface ShowMessageRequestParams { + /** + * The message type. See {@link MessageType} + */ + MessageType type = null; + + /** + * The actual message + */ + String message = null; + + /** + * The message action items to present. + */ + MessageActionItem[] actions = new MessageActionItem[0]; + } + + interface MessageActionItem { + /** + * A short title like 'Retry', 'Open Log' etc. + */ + String title = null; + } + + /** + * Show Document Request (:arrow_right_hook:) + * New in version 3.16.0 + *

+ * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. + *

+ * property path (optional): window.showDocument + * property type: ShowDocumentClientCapabilities defined as follows: + */ + @JsonRequest + ShowDocumentResult showDocument(ShowDocumentParams params); + + interface ShowDocumentParams { + /** + * The uri to show. + */ + String uri; + + /** + * Indicates to show the resource in an external program. + * To show, for example, `https://code.visualstudio.com/` + * in the default WEB browser set `external` to `true`. + */ + Boolean external; + + /** + * An optional property to indicate whether the editor + * showing the document should take focus or not. + * Clients might ignore this property if an external + * program is started. + */ + Boolean takeFocus; + + /** + * An optional selection range if the document is a text + * document. Clients might ignore the property if an + * external program is started or the file is not a text + * file. + */ + Range selection; + } + + defined + + interface ShowDocumentResult { + /** + * A boolean indicating if the show was successful. + */ + boolean success; + } + + /** + * LogMessage Notification(:arrow_left:) + *

+ * The log message notification is sent from the server to the client to ask the client to log + * a particular message. + */ + interface LogMessageParams { + /** + * The message type. See {@link MessageType} + */ + MessageType type; + + /** + * The actual message + */ + String message; + } + + /** + Create Work + + Done Progress(:arrow_right_hook:) + + The window/workDoneProgress/ create request is sent from the server to the client to ask + the clie nt to create a work done progress. + */ + + interface WorkDoneProgressCreateParams { + /** + * The token to be used to report progress. + */ + ProgressToken token; + } + + @JsonNotification workDoneProgressCancel(); + WorkDoneProgressCancelParams defined + interface WorkDoneProgressCancelParams { + /** + * The token to be used to report progress. + */ + ProgressToken token; + } + + + //endregion +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java new file mode 100644 index 00000000000..9578fb8b171 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java @@ -0,0 +1,9 @@ +package org.keyproject.key.remoteclient; + +class SimpleClient implements ClientApi { + + @Override + public void sayHello(String e) { + System.out.format("Hello, %s%n", e); + } +} diff --git a/settings.gradle b/settings.gradle index e71fc368308..a7fccaa51b6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,3 +13,5 @@ include 'keyext.ui.testgen' include 'keyext.proofmanagement' include 'keyext.exploration' include 'keyext.slicing' + +include 'keyext.api' From 8f2aec31f6670fd04bac06786b7687fd5a4cd0fc Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 8 Oct 2023 13:43:38 +0200 Subject: [PATCH 02/50] different clients --- keyext.api/build.gradle | 24 +- .../key/{ => api}/FileTypeAdapter.java | 2 +- .../key/{ => api}/remoteapi/KeyApi.java | 7 +- .../key/{ => api}/remoteapi/KeyApiImpl.java | 8 +- .../{ => api}/remoteapi/KeyExampleApi.java | 2 +- .../key/{ => api}/remoteapi/KeyMetaApi.java | 3 +- .../{ => api}/remoteapi/MacroDescription.java | 2 +- .../keyproject/key/api/remoteapi/ProofId.java | 4 + .../key/api/remoteapi/ProofLoading.java | 19 ++ .../key/{ => api}/remoteapi/TraceValue.java | 2 +- .../key/api/remoteclient/ClientApi.java | 65 +++++ .../org/keyproject/key/remoteapi/Main.java | 63 ----- .../org/keyproject/key/remoteapi/ProofId.java | 4 - .../key/remoteapi/ProofLoading.java | 67 ------ .../key/remoteclient/ClientApi.java | 224 ------------------ .../key/remoteclient/SimpleClient.java | 9 - keyext.api/src/main/python/keyapi/__init__.py | 17 ++ .../java/org/keyproject/key/api}/Client.java | 16 +- .../org/keyproject/key/api/SimpleClient.java | 35 +++ 19 files changed, 182 insertions(+), 391 deletions(-) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/FileTypeAdapter.java (93%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyApi.java (92%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyApiImpl.java (88%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyExampleApi.java (89%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyMetaApi.java (85%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/MacroDescription.java (86%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/TraceValue.java (54%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java create mode 100644 keyext.api/src/main/python/keyapi/__init__.py rename keyext.api/src/{main/java/org/keyproject/key/remoteclient => test/java/org/keyproject/key/api}/Client.java (80%) create mode 100644 keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index 463b7dbc11a..0f3b2743c24 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -1,6 +1,28 @@ +plugins { + id 'application' + + // Used to create a single executable jar file with all dependencies + // see task "shadowJar" below + // https://imperceptiblethoughts.com/shadow/ + id 'com.github.johnrengelman.shadow' version "8.1.1" +} + +description "Verification server interface via JSON-RPC" + dependencies { implementation(project(":key.core")) implementation(project(":key.ui")) implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") -} \ No newline at end of file + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") + implementation("org.eclipse.jetty.websocket:websocket-javax-server:10.0.16") + implementation("info.picocli:picocli:4.7.5") + //for GraalVM annotationProcessor 'info.picocli:picocli-codegen:4.7.5' +} + + +compileJava { + // for GraalVM options.compilerArgs += ["-Aproject=${project.group}/${project.name}"] +} + diff --git a/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java similarity index 93% rename from keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java rename to keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java index 67240012e90..9c03fdfae41 100644 --- a/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java @@ -1,4 +1,4 @@ -package org.keyproject.key; +package org.keyproject.key.api; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java similarity index 92% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index 76c2d1eefdd..9a6e35fe2eb 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -1,11 +1,8 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.gui.Example; -import de.uka.ilkd.key.gui.ExampleChooser; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import java.util.List; import java.util.concurrent.CompletableFuture; public interface KeyApi extends KeyExampleApi, KeyMetaApi { @@ -26,7 +23,7 @@ The shutdown request is sent from the client to the server. It asks the server t error: code and message set in case an exception happens during shutdown request. */ @JsonRequest - Void shutdown(); + CompletableFuture shutdown(); /** * Exit Notification (:arrow_right:) diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java similarity index 88% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java index 0a967998dac..33ae9c03aba 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.api.KeYApi; import de.uka.ilkd.key.gui.Example; @@ -13,7 +13,7 @@ import java.util.concurrent.CompletableFuture; @JsonSegment -class KeyApiImpl implements KeyApi { +public class KeyApiImpl implements KeyApi { @Override @JsonRequest public CompletableFuture> examples() { @@ -21,8 +21,8 @@ public CompletableFuture> examples() { } @Override - public Void shutdown() { - return null; + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(null); } @Override diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java similarity index 89% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java index f1fe80a6dfc..b1bc064b954 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.gui.Example; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java similarity index 85% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java index e5538b30896..df0112c51f2 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java @@ -1,7 +1,6 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; -import org.eclipse.lsp4j.jsonrpc.CompletableFutures; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java similarity index 86% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java index 2f34d3e03ed..ad6d12babf8 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.macros.ProofMacro; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java new file mode 100644 index 00000000000..7d1d4eb5d6b --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java @@ -0,0 +1,4 @@ +package org.keyproject.key.api.remoteapi; + +public record ProofId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java new file mode 100644 index 00000000000..49081037dc0 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java @@ -0,0 +1,19 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +@JsonSegment +public interface ProofLoading { + @JsonRequest + ProofId loadExample(String id); + + /** + * @param params + * @return + * @throws ProblemLoaderException + */ + @JsonRequest + EnvId load(LoadParams params) throws ProblemLoaderException; +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java similarity index 54% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java index 1d1d4859e57..567b740d6d8 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; public enum TraceValue { Off, Message, All; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java new file mode 100644 index 00000000000..6f02b10a186 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -0,0 +1,65 @@ +package org.keyproject.key.api.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import javax.annotation.Nullable; +import java.util.concurrent.CompletableFuture; + +@JsonSegment +public interface ClientApi { + @JsonNotification + void sayHello(String e); + + /** + * LogTrace Notification (:arrow_left:) + * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. + *

+ * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. + *

+ * Notification: + *

+ * method: ‘$/logTrace’ + * params: LogTraceParams defined as follows: + */ + @JsonNotification + void logTrace(LogTraceParams params); + //region Window + + /** + * ShowMessage Notification (:arrow_left:) + * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. + *

+ * Notification: + *

+ * method: ‘window/showMessage’ + * params: ShowMessageParams defined as follows: + */ + @JsonNotification("sm") + void showMessage(ShowMessageParams params); + + + + /** + * ShowMessage Request (:arrow_right_hook:) + * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. + */ + @JsonRequest + @Nullable + CompletableFuture userResponse(ShowMessageRequestParams params); + + + /** + * Show Document Request (:arrow_right_hook:) + * New in version 3.16.0 + *

+ * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. + *

+ * property path (optional): window.showDocument + * property type: ShowDocumentClientCapabilities defined as follows: + */ + @JsonRequest + CompletableFuture showDocument(ShowDocumentParams params); + //endregion +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java deleted file mode 100644 index 127b36a702c..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.keyproject.key.remoteapi; - -import com.google.gson.GsonBuilder; -import org.eclipse.lsp4j.jsonrpc.Launcher; -import org.keyproject.key.FileTypeAdapter; -import org.keyproject.key.remoteclient.ClientApi; - -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ExecutionException; - -public class Main { - public static void main(String[] args) throws ExecutionException, InterruptedException { - var future = launch(System.out, System.in); - future.startListening(); - } - - public static Launcher launch(OutputStream out, InputStream in) { - var localServices = getLocalServices(); - var remoteInterfaces = getRemoteInterfaces(); - var launcherBuilder = new Launcher.Builder() - .setOutput(out) - .setInput(in) - .traceMessages(new PrintWriter(System.err)) - .validateMessages(true); - - launcherBuilder.configureGson(Main::configureJson); - - //if (localServices != null && !localServices.isEmpty()) - launcherBuilder.setLocalService(new KeyApiImpl()); - //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) - launcherBuilder.setRemoteInterface(ClientApi.class); - - var launcher = launcherBuilder.create(); - return launcher; - } - - public static void configureJson(GsonBuilder gsonBuilder) { - gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); - } - - private static Collection> getRemoteInterfaces() { - return Collections.singleton(ClientApi.class); - /* return ServiceLoader.load(ClientService.class) - .stream() - .map(ServiceLoader.Provider::type) - .collect(Collectors.toSet()); - */ - } - - private static List getLocalServices() { - return Collections.singletonList(new KeyApiImpl()); - /*return ServiceLoader.load(KeyService.class) - .stream().map(ServiceLoader.Provider::get) - .map(it -> (Object) it) - .toList();*/ - } -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java deleted file mode 100644 index 65db8662e4e..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.keyproject.key.remoteapi; - -public record ProofId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java deleted file mode 100644 index 7e99ffd0cf5..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.keyproject.key.remoteapi; - -import de.uka.ilkd.key.api.ProofManagementApi; -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.io.ProblemLoaderException; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - -import java.io.File; -import java.util.List; - -@JsonSegment -public interface ProofLoading { - @JsonRequest ProofId loadExample(String id); - - interface LoadParams { - File keyFile; - File javaFile; - - List classPath, - File bootClassPath, List includes - } - - /** - * @param keyFile - * @return - * @throws ProblemLoaderException - */ - @JsonRequest ProofId loadFromKeyFile(File keyFile) throws ProblemLoaderException { - return new ProofManagementApi(KeYEnvironment.load(keyFile)); - } - - /** - * @param location - * @param classPath - * @param bootClassPath - * @param includes - * @return - * @throws ProblemLoaderException - */ - @JsonRequest ProofId loadProof(File location, List classPath, - File bootClassPath, List includes) throws ProblemLoaderException { - return new ProofManagementApi( - KeYEnvironment.load(location, classPath, bootClassPath, includes)); - } - - /** - * @param javaSourceCode - * @return - * @throws ProblemLoaderException - */ - @JsonRequest ProofId loadProof(File javaSourceCode) throws ProblemLoaderException { - return loadProof(javaSourceCode, null, null, null); - } - - /** - * Load a proof file, creates a KeY environment that can be accessed with other methods from - * this facade - * - * @param file Path to the source code folder/file or to a *.proof file - * @param classPaths Optionally: Additional specifications for API classes - * @param bootClassPath Optionally: Different default specifications for Java API - * @param includes Optionally: Additional includes to consider - */ - @JsonRequest ProofId loadProofFile(File file, List classPaths, File bootClassPath, - List includes); -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java deleted file mode 100644 index 23c3ddf9e39..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.keyproject.key.remoteclient; - -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.eclipse.lsp4j.jsonrpc.validation.NonNull; - -import javax.annotation.Nullable; - -@JsonSegment -public interface ClientApi { - @JsonNotification - void sayHello(String e); - - /** - * LogTrace Notification (:arrow_left:) - * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. - *

- * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. - *

- * Notification: - *

- * method: ‘$/logTrace’ - * params: LogTraceParams defined as follows: - */ - @JsonNotification - void logTrace(LogTraceParams params); - - interface LogTraceParams { - /** - * The message to be logged. - */ - @NonNull - String message = null; - /** - * Additional information that can be computed if the `trace` configuration - * is set to `'verbose'` - */ - String verbose = null; - } - - //region Window - - /** - * ShowMessage Notification (:arrow_left:) - * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. - *

- * Notification: - *

- * method: ‘window/showMessage’ - * params: ShowMessageParams defined as follows: - */ - @JsonNotification - public void ShowMessage(ShowMessageParams params); - - interface ShowMessageParams { - /** - * The message type. See {@link MessageType}. - */ - MessageType type = null; - - /** - * The actual message. - */ - String message = null; - } - - enum MessageType { - - Unused, - /** - * An error message. - */ - Error, - /** - * A warning message. - */ - Warning, - /** - * An information message. - */ - Info, - /** - * A log message. - */ - Log, - /** - * A debug message. - * - * @proposed - * @since 3.18.0 - */ - Debug - } - - /** - * ShowMessage Request (:arrow_right_hook:) - * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. - */ - @JsonRequest - @Nullable - MessageActionItem ShowMessage(ShowMessageRequestParams params); - - interface ShowMessageRequestParams { - /** - * The message type. See {@link MessageType} - */ - MessageType type = null; - - /** - * The actual message - */ - String message = null; - - /** - * The message action items to present. - */ - MessageActionItem[] actions = new MessageActionItem[0]; - } - - interface MessageActionItem { - /** - * A short title like 'Retry', 'Open Log' etc. - */ - String title = null; - } - - /** - * Show Document Request (:arrow_right_hook:) - * New in version 3.16.0 - *

- * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. - *

- * property path (optional): window.showDocument - * property type: ShowDocumentClientCapabilities defined as follows: - */ - @JsonRequest - ShowDocumentResult showDocument(ShowDocumentParams params); - - interface ShowDocumentParams { - /** - * The uri to show. - */ - String uri; - - /** - * Indicates to show the resource in an external program. - * To show, for example, `https://code.visualstudio.com/` - * in the default WEB browser set `external` to `true`. - */ - Boolean external; - - /** - * An optional property to indicate whether the editor - * showing the document should take focus or not. - * Clients might ignore this property if an external - * program is started. - */ - Boolean takeFocus; - - /** - * An optional selection range if the document is a text - * document. Clients might ignore the property if an - * external program is started or the file is not a text - * file. - */ - Range selection; - } - - defined - - interface ShowDocumentResult { - /** - * A boolean indicating if the show was successful. - */ - boolean success; - } - - /** - * LogMessage Notification(:arrow_left:) - *

- * The log message notification is sent from the server to the client to ask the client to log - * a particular message. - */ - interface LogMessageParams { - /** - * The message type. See {@link MessageType} - */ - MessageType type; - - /** - * The actual message - */ - String message; - } - - /** - Create Work - - Done Progress(:arrow_right_hook:) - - The window/workDoneProgress/ create request is sent from the server to the client to ask - the clie nt to create a work done progress. - */ - - interface WorkDoneProgressCreateParams { - /** - * The token to be used to report progress. - */ - ProgressToken token; - } - - @JsonNotification workDoneProgressCancel(); - WorkDoneProgressCancelParams defined - interface WorkDoneProgressCancelParams { - /** - * The token to be used to report progress. - */ - ProgressToken token; - } - - - //endregion -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java deleted file mode 100644 index 9578fb8b171..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.keyproject.key.remoteclient; - -class SimpleClient implements ClientApi { - - @Override - public void sayHello(String e) { - System.out.format("Hello, %s%n", e); - } -} diff --git a/keyext.api/src/main/python/keyapi/__init__.py b/keyext.api/src/main/python/keyapi/__init__.py new file mode 100644 index 00000000000..8523f3801f5 --- /dev/null +++ b/keyext.api/src/main/python/keyapi/__init__.py @@ -0,0 +1,17 @@ +from keyapi.rpc import JsonRPCHandler, Client + + +class KeyClient(Client): + def __int__(self): + pass + + def handle(self, res): + print(res) + + +class KeyStub(JsonRPCHandler): + def __init__(self, input, output): + super().__init__(input, output) + + def list_examples(self): + return self._send("examples/list", []) diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java b/keyext.api/src/test/java/org/keyproject/key/api/Client.java similarity index 80% rename from keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java rename to keyext.api/src/test/java/org/keyproject/key/api/Client.java index 4fd0b792189..4922de0993a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/Client.java @@ -1,16 +1,18 @@ -package org.keyproject.key.remoteclient; +package org.keyproject.key.api; import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; -import org.keyproject.key.remoteapi.Main; -import org.keyproject.key.remoteapi.KeyApi; +import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteclient.ClientApi; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintWriter; import java.util.Collections; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,7 +26,7 @@ public static void main(String[] args) throws IOException, ExecutionException, I inClient.connect(outServer); outClient.connect(inServer); - Launcher serverLauncher = Main.launch(outServer, inServer); + Launcher serverLauncher = StartServer.launch(outServer, inServer); var client = new SimpleClient(); Launcher clientLauncher = new Launcher.Builder() @@ -32,7 +34,7 @@ public static void main(String[] args) throws IOException, ExecutionException, I .setRemoteInterfaces(Collections.singleton(KeyApi.class)) .setInput(inClient) .setOutput(outClient) - .configureGson(Main::configureJson) + .configureGson(StartServer::configureJson) .traceMessages(new PrintWriter(System.err)) .create(); @@ -49,5 +51,3 @@ public static void main(String[] args) throws IOException, ExecutionException, I clientListening.get(1, TimeUnit.SECONDS); } } - - diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java new file mode 100644 index 00000000000..3370f6eb31f --- /dev/null +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -0,0 +1,35 @@ +package org.keyproject.key.api; + +import org.keyproject.key.api.remoteclient.*; + +import javax.annotation.Nullable; +import java.util.concurrent.CompletableFuture; + +class SimpleClient implements ClientApi { + + @Override + public void sayHello(String e) { + System.out.format("Hello, %s%n", e); + } + + @Override + public void logTrace(LogTraceParams params) { + + } + + @Override + public void userResponse(ShowMessageParams params) { + + } + + @Nullable + @Override + public CompletableFuture userResponse(ShowMessageRequestParams params) { + return null; + } + + @Override + public CompletableFuture showDocument(ShowDocumentParams params) { + return null; + } +} From 963386f76519e5955625cce39a5f9adbbf99a2f3 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Fri, 13 Oct 2023 13:26:27 +0200 Subject: [PATCH 03/50] wip --- .../org/keyproject/key/api/StartServer.java | 203 ++++++++++++++++++ .../keyproject/key/api/remoteapi/EnvId.java | 8 + .../key/api/remoteapi/LoadParams.java | 8 + .../api/remoteclient/LogMessageParams.java | 15 ++ .../key/api/remoteclient/LogTraceParams.java | 19 ++ .../api/remoteclient/MessageActionItem.java | 9 + .../key/api/remoteclient/MessageType.java | 28 +++ .../api/remoteclient/ShowDocumentParams.java | 35 +++ .../api/remoteclient/ShowDocumentResult.java | 10 + .../api/remoteclient/ShowMessageParams.java | 14 ++ .../ShowMessageRequestParams.java | 20 ++ keyext.api/src/main/python/keyapi/rpc.py | 76 +++++++ keyext.api/src/main/python/main.py | 13 ++ 13 files changed, 458 insertions(+) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/StartServer.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java create mode 100644 keyext.api/src/main/python/keyapi/rpc.py create mode 100644 keyext.api/src/main/python/main.py diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java new file mode 100644 index 00000000000..26837bb84b6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -0,0 +1,203 @@ +package org.keyproject.key.api; + + +import com.google.gson.GsonBuilder; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.websocket.jakarta.WebSocketLauncherBuilder; +import org.keyproject.key.api.remoteapi.KeyApiImpl; +import org.keyproject.key.api.remoteclient.ClientApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; +import picocli.CommandLine.Option; + +import javax.annotation.Nullable; +import java.io.*; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @author Alexander Weigl + * @version 1 (07.10.23) + */ +@CommandLine.Command +public class StartServer implements Runnable { + private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); + + //region CLI arguments + @Option(names = "--std", description = "use stdout and stdin for communication") + boolean stdStreams; + @Option(names = "--trace", description = "use stdout and stdin for communication") + boolean enableTracing; + + @Option(names = "--server", paramLabel = "PORT", description = "enables the TCP server mode") + @Nullable + Integer serverPort; + + @Option(names = "--connectTo", paramLabel = "PORT", description = "enables the TCP client mode") + @Nullable + Integer clientPort; + + + @Option(names = "--infile", paramLabel = "FILE or PIPE", description = "read from named pipe or file") + @Nullable + File inFile; + + @Option(names = "--outfile", paramLabel = "FILE or PIPE", description = "write to named pipe or file") + File outFile; + + @Option(names = {"-h", "--help"}, usageHelp = true, description = "display a help message") + boolean helpRequested = false; + + @Option(names = "--websocket") + boolean websocket; + //endregion + + public static void main(String[] args) { + new CommandLine(new StartServer()).execute(args); + } + + private InputStream in; + private OutputStream out; + + private void establishStreams() throws IOException { + in = System.in; + out = System.out; + + if (stdStreams) { + return; + } + + if (clientPort != null) { + var socket = new Socket(InetAddress.getLocalHost(), clientPort); + socket.setKeepAlive(true); + socket.setTcpNoDelay(true); + in = socket.getInputStream(); + out = socket.getOutputStream(); + return; + } + + if (serverPort != null) { + var server = new ServerSocket(serverPort); + LOGGER.info("Waiting on port {}", serverPort); + var socket = server.accept(); + LOGGER.info("Connection to client established: {}", socket.getRemoteSocketAddress()); + socket.setKeepAlive(true); + socket.setTcpNoDelay(true); + in = socket.getInputStream(); + out = socket.getOutputStream(); + return; + } + + + if (inFile != null) { + in = new FileInputStream(inFile); + } + + if (outFile != null) { + out = new FileOutputStream(outFile); + } + + if (out == null || in == null) { + throw new IllegalStateException("Could not initialize the streams"); + } + } + + + @Override + public void run() { + if (helpRequested) { + return; + } + + /* + var server = new Server(); + var connector = new ServerConnector(); + server.addConnector(connector); + // Setup the basic application "context" for this application at "/" + // This is also known as the handler tree (in jetty speak) + var context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + server.setHandler(context); + + // Initialize javax.websocket layer + JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> + { + // Configure defaults for container + wsContainer.setDefaultMaxTextMessageBufferSize(65535); + + // Add WebSocket endpoint to javax.websocket layer + wsContainer.addEndpoint(WebSocketEndpoint.class); + });*/ + + + try { + if (websocket) { + var launcherBuilder = new WebSocketLauncherBuilder() + .setOutput(out) + .setInput(in) + .traceMessages(new PrintWriter(System.err)) + .validateMessages(true); + launcherBuilder.configureGson(StartServer::configureJson); + launcherBuilder.setLocalService(new KeyApiImpl()); + launcherBuilder.setRemoteInterface(ClientApi.class); + launcherBuilder.create().startListening().get(); + } else { + establishStreams(); + try (var lin = in; var lout = out) { + var listener = launch(lout, lin); + LOGGER.info("JSON-RPC is listening for requests"); + listener.startListening().get(); + } + } + } catch (IOException | InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + public static void configureJson(GsonBuilder gsonBuilder) { + gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); + } + + public static Launcher launch(OutputStream out, InputStream in) { + // var localServices = getLocalServices(); + // var remoteInterfaces = getRemoteInterfaces(); + var launcherBuilder = new Launcher.Builder() + .setOutput(out) + .setInput(in) + .traceMessages(new PrintWriter(System.err)) + .validateMessages(true); + + launcherBuilder.configureGson(StartServer::configureJson); + + //if (localServices != null && !localServices.isEmpty()) + launcherBuilder.setLocalService(new KeyApiImpl()); + //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) + launcherBuilder.setRemoteInterface(ClientApi.class); + + return launcherBuilder.create(); + } + + + private static Collection> getRemoteInterfaces() { + return Collections.singleton(ClientApi.class); + /* return ServiceLoader.load(ClientService.class) + .stream() + .map(ServiceLoader.Provider::type) + .collect(Collectors.toSet()); + */ + } + + private static List getLocalServices() { + return Collections.singletonList(new KeyApiImpl()); + /*return ServiceLoader.load(KeyService.class) + .stream().map(ServiceLoader.Provider::get) + .map(it -> (Object) it) + .toList();*/ + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java new file mode 100644 index 00000000000..3a2b5291d66 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.remoteapi; + +/** + * @author Alexander Weigl + * @version 1 (06.10.23) + */ +public record EnvId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java new file mode 100644 index 00000000000..7eadda846ba --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.remoteapi; + +import java.io.File; +import java.util.List; + +public record LoadParams(File keyFile, File javaFile, List classPath, File bootClassPath, List includes) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java new file mode 100644 index 00000000000..7ae00a584e7 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java @@ -0,0 +1,15 @@ +package org.keyproject.key.api.remoteclient; + +record LogMessageParams( + /** + * The message type. See {@link MessageType} + */ + MessageType type, + + /** + * The actual message + */ + String message +) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java new file mode 100644 index 00000000000..b5995ff5220 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java @@ -0,0 +1,19 @@ +package org.keyproject.key.api.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.validation.NonNull; + +public record LogTraceParams( + /** + * The message to be logged. + */ + @NonNull + String messag, + + /** + * Additional information that can be computed if the `trace` configuration + * is set to `'verbose'` + */ + String verbose +) { + +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java new file mode 100644 index 00000000000..df586cac66d --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.remoteclient; + +public record MessageActionItem( + /** + * A short title like 'Retry', 'Open Log' etc. + */ + String title +) { +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java new file mode 100644 index 00000000000..cb8c20dd311 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java @@ -0,0 +1,28 @@ +package org.keyproject.key.api.remoteclient; + +public enum MessageType { + Unused, + /** + * An error message. + */ + Error, + /** + * A warning message. + */ + Warning, + /** + * An information message. + */ + Info, + /** + * A log message. + */ + Log, + /** + * A debug message. + * + * @proposed + * @since 3.18.0 + */ + Debug + } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java new file mode 100644 index 00000000000..17502b1a910 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java @@ -0,0 +1,35 @@ +package org.keyproject.key.api.remoteclient; + +import de.uka.ilkd.key.pp.Range; + +public record ShowDocumentParams( + /** + * The uri to show. + */ + String uri, + + /** + * Indicates to show the resource in an external program. + * To show, for example, `https://code.visualstudio.com/` + * in the default WEB browser set `external` to `true`. + */ + Boolean external, + + /** + * An optional property to indicate whether the editor + * showing the document should take focus or not. + * Clients might ignore this property if an external + * program is started. + */ + Boolean takeFocus, + + /** + * An optional selection range if the document is a text + * document. Clients might ignore the property if an + * external program is started or the file is not a text + * file. + */ + Range selection +) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java new file mode 100644 index 00000000000..b91a100858a --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api.remoteclient; + +public record ShowDocumentResult( + /** + * A boolean indicating if the show was successful. + */ + boolean success +) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java new file mode 100644 index 00000000000..9bf22a6f552 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java @@ -0,0 +1,14 @@ +package org.keyproject.key.api.remoteclient; + +public record ShowMessageParams( + /** + * The message type. See {@link MessageType}. + */ + MessageType type, + + /** + * The actual message. + */ + String message) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java new file mode 100644 index 00000000000..5e5f4f1410b --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java @@ -0,0 +1,20 @@ +package org.keyproject.key.api.remoteclient; + +public record ShowMessageRequestParams( + /** + * The message type. See {@link MessageType} + */ + MessageType type, + + /** + * The actual message + */ + String message, + + /** + * The message action items to present. + * + */ + MessageActionItem[] actions +) { +} \ No newline at end of file diff --git a/keyext.api/src/main/python/keyapi/rpc.py b/keyext.api/src/main/python/keyapi/rpc.py new file mode 100644 index 00000000000..89dc6f3e041 --- /dev/null +++ b/keyext.api/src/main/python/keyapi/rpc.py @@ -0,0 +1,76 @@ +import abc +import json +from abc import abstractmethod +from multiprocessing import Process, SimpleQueue, Lock, Value + + +class Client(abc.ABC): + @abstractmethod + def handle(self, response): + pass + + +class JsonRPCHandler: + client: Client + + def __init__(self, in_stream, out_stream): + self.input = in_stream + self.out = out_stream + self.__id = 0 + self.client: Client + + self._events = dict() + self._responses = dict() + + # t: Process = Process(target=self.__read) + # t.start() + + def read_message(self): + length = 0 + for clength in self.input.readlines(): + if clength.startswith("Content-Length:"): + length = int(clength[14:]) + break + + payload = self.input.read(2 + length) + r = json.loads(payload) + if "id" in r: # JSON response for request + rid = r["id"] + # self._responses[rid] = r + # if rid in self._events: + # self._events[rid].set() + else: # JSON notification + self.client.handle(r) + return r + + def __read(self): + while True: + self.read_message() + + # def __create_event(self, number): + # self._events[number] = Event() + + def _send(self, method, params): + self.__id += 1 + id = self.__id + # self.__create_event(self.__id) + req = {"jsonrpc": "2.0", "method": method, "params": params, "id": self.__id} + + self._write(json.dumps(req)) + # self._wait_for(self.__id) + + r = dict() + while "id" in r and str(r[id]) != str(id): + r = self.read_message() + return r + + def _write(self, msg): + length = len(msg) + self.out.write(f"Content-Length: {length}\r\n") + self.out.write("\r\n") + self.out.write(msg) + self.out.write("\r\n") + self.out.flush() + + # def _wait_for(self, rid): + # self._events[rid].wait() diff --git a/keyext.api/src/main/python/main.py b/keyext.api/src/main/python/main.py new file mode 100644 index 00000000000..a5cb45321d8 --- /dev/null +++ b/keyext.api/src/main/python/main.py @@ -0,0 +1,13 @@ +import socket +from keyapi import KeyStub, KeyClient + +if __name__ == "__main__": + target = ("localhost", 5151) + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect(target) + input = s.makefile("r", newline="\r\n") + output = s.makefile("w", newline="\r\n") + stub = KeyStub(input, output) + stub.client = KeyClient() + print(stub.list_examples()) From 3a8512a278d44330a5e415ded8c5d6ebb91999e0 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 15 Oct 2023 17:27:16 +0200 Subject: [PATCH 04/50] Creating an JSON-RPC API --- .../java/de/uka/ilkd/key/Identifiable.java | 11 + .../main/java/de/uka/ilkd/key/api/KeYApi.java | 102 --------- .../java/de/uka/ilkd/key/api/Matcher.java | 210 ------------------ .../de/uka/ilkd/key/api/ProjectedNode.java | 65 ------ .../java/de/uka/ilkd/key/api/ProofApi.java | 90 -------- .../uka/ilkd/key/api/ProofManagementApi.java | 129 ----------- .../ilkd/key/api/ProofScriptCommandCall.java | 20 -- .../java/de/uka/ilkd/key/api/ScriptApi.java | 132 ----------- .../de/uka/ilkd/key/api/ScriptResult.java | 114 ---------- .../de/uka/ilkd/key/api/ScriptResults.java | 178 --------------- .../java/de/uka/ilkd/key/api/SearchNode.java | 55 ----- .../uka/ilkd/key/api/VariableAssignments.java | 154 ------------- .../de/uka/ilkd/key/api/package-info.java | 9 - .../uka/ilkd/key/control/KeYEnvironment.java | 162 +++++++++----- .../ProofMacroFacade.java} | 15 +- .../scripts/ProofScriptCommandFacade.java} | 16 +- .../main/java/de/uka/ilkd/key/proof/Goal.java | 47 +++- .../java/de/uka/ilkd/key/proof/Proof.java | 12 +- .../speclang/njml/ContractLoadingTests.java | 65 ++---- .../de/uka/ilkd/key/gui/ExampleChooser.java | 2 +- keyext.api.doc/build.gradle | 4 + .../src/main/java/ExtractMetaData.java | 162 ++++++++++++++ keyext.api/build.gradle | 3 + .../keyproject/key/api/FileTypeAdapter.java | 20 -- .../org/keyproject/key/api/KeyApiImpl.java | 168 ++++++++++++++ .../org/keyproject/key/api/StartServer.java | 56 +---- .../key/api/adapters/KeyAdapter.java | 96 ++++++++ .../key/api/adapters/package-info.java | 7 + .../keyproject/key/api/data/ContractDesc.java | 8 + .../keyproject/key/api/data/FunctionDesc.java | 10 + .../org/keyproject/key/api/data/GoalText.java | 10 + .../keyproject/key/api/data/LoadParams.java | 14 ++ .../{remoteapi => data}/MacroDescription.java | 8 +- .../key/api/data/MacroStatistic.java | 8 + .../org/keyproject/key/api/data/NodeDesc.java | 8 + .../key/api/data/PredicateDesc.java | 8 + .../org/keyproject/key/api/data/PrintId.java | 8 + .../key/api/data/ProblemDefinition.java | 18 ++ .../keyproject/key/api/data/ProofLoading.java | 42 ++++ .../org/keyproject/key/api/data/SortDesc.java | 8 + .../key/api/data/StreategyOptions.java | 8 + .../keyproject/key/api/data/TermAction.java | 8 + .../keyproject/key/api/data/TermActionId.java | 8 + .../api/{remoteapi => data}/TraceValue.java | 2 +- .../keyproject/key/api/data/TreeNodeDesc.java | 8 + .../keyproject/key/api/data/TreeNodeId.java | 8 + .../keyproject/key/api/remoteapi/EnvApi.java | 31 +++ .../keyproject/key/api/remoteapi/EnvId.java | 8 - .../{KeyExampleApi.java => ExampleApi.java} | 2 +- .../keyproject/key/api/remoteapi/GoalApi.java | 32 +++ .../keyproject/key/api/remoteapi/KeyApi.java | 56 +---- .../key/api/remoteapi/KeyApiImpl.java | 56 ----- .../key/api/remoteapi/LoadParams.java | 8 - .../{KeyMetaApi.java => MetaApi.java} | 11 +- .../key/api/remoteapi/ProofApi.java | 48 ++++ .../keyproject/key/api/remoteapi/ProofId.java | 4 - .../key/api/remoteapi/ProofLoading.java | 19 -- .../key/api/remoteapi/ProofTreeApi.java | 26 +++ .../key/api/remoteapi/ServerManagement.java | 60 +++++ .../key/api/remoteclient/ClientApi.java | 2 +- .../org/keyproject/key/api/SimpleClient.java | 2 +- .../key/api/{Client.java => TestRpc.java} | 45 +++- settings.gradle | 1 + 63 files changed, 1093 insertions(+), 1614 deletions(-) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/Identifiable.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/package-info.java rename key.core/src/main/java/de/uka/ilkd/key/{api/ProofMacroApi.java => macros/ProofMacroFacade.java} (83%) rename key.core/src/main/java/de/uka/ilkd/key/{api/ProofScriptCommandApi.java => macros/scripts/ProofScriptCommandFacade.java} (79%) create mode 100644 keyext.api.doc/build.gradle create mode 100644 keyext.api.doc/src/main/java/ExtractMetaData.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java rename keyext.api/src/main/java/org/keyproject/key/api/{remoteapi => data}/MacroDescription.java (72%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java rename keyext.api/src/main/java/org/keyproject/key/api/{remoteapi => data}/TraceValue.java (54%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java rename keyext.api/src/main/java/org/keyproject/key/api/remoteapi/{KeyExampleApi.java => ExampleApi.java} (91%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java rename keyext.api/src/main/java/org/keyproject/key/api/remoteapi/{KeyMetaApi.java => MetaApi.java} (64%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java rename keyext.api/src/test/java/org/keyproject/key/api/{Client.java => TestRpc.java} (57%) diff --git a/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java b/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java new file mode 100644 index 00000000000..3be1d2528d8 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java @@ -0,0 +1,11 @@ +package de.uka.ilkd.key; + +/** + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +public interface Identifiable { + default String identification() { + return getClass().getName() + "_" + hashCode(); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java deleted file mode 100644 index dc89908c39c..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.io.File; -import java.util.List; - -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.io.ProblemLoaderException; -import de.uka.ilkd.key.util.KeYConstants; - -/** - * The Entry Point. - *

- * This facility is the entry point to the different KeY apis. Currently it support the - * bootstrapping of the {@link KeYEnvironment} and the loading of proofs. - *

- * Created at 6.4.17 - * - * @author Sarah Grebing - * @author Alexander Weigl - * @see ProofScriptCommandApi - */ -public abstract class KeYApi { - private static final ProofMacroApi proofMacroApi = new ProofMacroApi(); - private static final ProofScriptCommandApi scriptCommandApi = new ProofScriptCommandApi(); - - /** - * Create a new KeY API and create the sub APIs - */ - private KeYApi() { - } - - /** - * - * @return - */ - public static String getVersion() { - return KeYConstants.INTERNAL_VERSION; - } - - - /** - * @return non-null - */ - public static ProofScriptCommandApi getScriptCommandApi() { - return scriptCommandApi; - } - - /** - * @return a non-null references to the macro api - */ - public static ProofMacroApi getMacroApi() { - return proofMacroApi; - } - - /** - * @param keyFile - * @return - * @throws ProblemLoaderException - */ - public static ProofManagementApi loadFromKeyFile(File keyFile) throws ProblemLoaderException { - return new ProofManagementApi(KeYEnvironment.load(keyFile)); - } - - /** - * @param location - * @param classPath - * @param bootClassPath - * @param includes - * @return - * @throws ProblemLoaderException - */ - public static ProofManagementApi loadProof(File location, List classPath, - File bootClassPath, List includes) throws ProblemLoaderException { - return new ProofManagementApi( - KeYEnvironment.load(location, classPath, bootClassPath, includes)); - } - - /** - * @param javaSourceCode - * @return - * @throws ProblemLoaderException - */ - public static ProofManagementApi loadProof(File javaSourceCode) throws ProblemLoaderException { - return loadProof(javaSourceCode, null, null, null); - } - - /** - * Load a proof file, creates a KeY environment that can be accessed with other methods from - * this facade - * - * @param file Path to the source code folder/file or to a *.proof file - * @param classPaths Optionally: Additional specifications for API classes - * @param bootClassPath Optionally: Different default specifications for Java API - * @param includes Optionally: Additional includes to consider - */ - public abstract void loadProofFile(File file, List classPaths, File bootClassPath, - List includes); - -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java b/key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java deleted file mode 100644 index 2c628c45ff2..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java +++ /dev/null @@ -1,210 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.*; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.Name; -import de.uka.ilkd.key.logic.Sequent; -import de.uka.ilkd.key.logic.SequentFormula; -import de.uka.ilkd.key.logic.op.SchemaVariable; -import de.uka.ilkd.key.nparser.KeyAst; -import de.uka.ilkd.key.nparser.KeyIO; -import de.uka.ilkd.key.nparser.ParsingFacade; -import de.uka.ilkd.key.rule.*; -import de.uka.ilkd.key.rule.inst.SVInstantiations; -import de.uka.ilkd.key.rule.match.vm.VMTacletMatcher; - -import org.key_project.util.collection.ImmutableArray; -import org.key_project.util.collection.ImmutableList; - -import org.antlr.v4.runtime.CharStreams; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Matcher to deal with matching a string pattern against a sequent - * - * @author S.Grebing - */ -public class Matcher { - private static final Logger LOGGER = LoggerFactory.getLogger(Matcher.class); - private final ProofApi api; - - /** - * Creates a new matcher for the given proof and environment. - * - * @param api reference to proof api in order to get access to the key environment - */ - public Matcher(ProofApi api) { - this.api = api; - } - - /** - * Matches a sequent against a sequent pattern (a schematic sequent) returns a list of Nodes - * containing matching results from where the information about instantiated schema variables - * can be extracted. If no match was possible the list is exmpt. - * - * @param pattern a string representation of the pattern sequent against which the current - * sequent should be matched - * @param currentSeq current concrete sequent - * @param assignments variables appearing in the pattern as schemavariables with their - * corresponding type in KeY - * @return List of VariableAssignments (possibly empty if no match was found) - */ - // List of VarAssignment - public List matchPattern(String pattern, Sequent currentSeq, - VariableAssignments assignments) { - // copy services in order to not accidently set assignments and namespace for environment - Services copyServices = api.getEnv().getServices().copy(false); - // Aufbau der Deklarationen fuer den NameSpace - buildNameSpace(assignments, copyServices); - // Zusammenbau des Pseudotaclets - // Parsen des Taclets - String patternString = "matchPattern{\\assumes(" + pattern + ") \\find (==>) \\add (==>)}"; - - Taclet t = parseTaclet(patternString, copyServices); - - // Build Matcher for Matchpattern - VMTacletMatcher tacletMatcher = new VMTacletMatcher(t); - - // patternSequent should not be null, as we have created it - assert t.ifSequent() != null; - Sequent patternSeq = t.ifSequent(); - int asize = patternSeq.antecedent().size(); - int size = asize + patternSeq.succedent().size(); - // Iterator durch die Pattern-Sequent - - List finalCandidates = new ArrayList<>(100); - if (size > 0) { - // Iteratoren durch die Sequent - ImmutableArray antecCand = - IfFormulaInstSeq.createList(currentSeq, true, copyServices); - ImmutableArray succCand = - IfFormulaInstSeq.createList(currentSeq, false, copyServices); - - SequentFormula[] patternArray = new SequentFormula[patternSeq.size()]; - int i = 0; - for (SequentFormula fm : patternSeq) { - patternArray[i++] = fm; - } - - - Queue queue = new LinkedList<>(); - // init - queue.add(new SearchNode(patternArray, asize)); - - - while (!queue.isEmpty()) { - SearchNode node = queue.remove(); - boolean inAntecedent = node.isAntecedent(); - LOGGER.debug(inAntecedent ? "In Antec: " : "In Succ"); - - IfMatchResult ma = tacletMatcher.matchIf((inAntecedent ? antecCand : succCand), - node.getPatternTerm(), node.getMatchConditions(), copyServices); - - if (!ma.getMatchConditions().isEmpty()) { - ImmutableList testma = ma.getMatchConditions(); - - for (MatchConditions matchConditions : testma) { - SearchNode sn = new SearchNode(node, matchConditions); - if (sn.isFinished()) { - finalCandidates.add(sn); - } else { - queue.add(sn); - } - } - } else { - LOGGER.debug("Pattern Empty"); - } - } - } - List matches = new ArrayList<>(); - if (!finalCandidates.isEmpty()) { - for (SearchNode finalCandidate : finalCandidates) { - VariableAssignments va = extractAssignments(finalCandidate, assignments); - matches.add(va); - } - } - return matches; - } - - /** - * Extract the matching results from each SearchNode and tranform these to Variable Assigments - * - * @param sn SearchNode - * @return VariableAssigments containing the assignments fo matching results to schemavariables - */ - private VariableAssignments extractAssignments(SearchNode sn, VariableAssignments assignments) { - VariableAssignments va = new VariableAssignments(); - SVInstantiations insts = sn.getInstantiations(); - Set varNames = assignments.getTypeMap().keySet(); - for (String varName : varNames) { - SchemaVariable sv = insts.lookupVar(new Name(varName)); - Object value = insts.getInstantiation(sv); - va.addAssignmentWithType(varName, value, assignments.getTypeMap().get(varName)); - } - return va; - - } - - /** - * Adds the variables of VariableAssignments to the namespace - * - * @param assignments VariabelAssignments containing variable names and types - */ - private void buildNameSpace(VariableAssignments assignments, Services services) { - String decalarations = buildDecls(assignments); - parseDecls(decalarations, services); - - } - - /** - * Builds a string that is used to create a new schemavariable declaration for the matchpattern - * - * @param assignments varaiables appearing as schema varaibels in the match pattern and their - * types (in KeY) - * @return a String representing the declaration part of a taclet for teh matchpattern - */ - private String buildDecls(VariableAssignments assignments) { - Map typeMap = assignments.getTypeMap(); - String schemaVars = "\\schemaVariables {\n"; - final List strn = new ArrayList<>(); - - typeMap.forEach((id, type) -> strn.add(toDecl(id, type))); - schemaVars += String.join("\n", strn); - schemaVars += "}"; - LOGGER.debug("Schema Variables: {}", schemaVars); - return schemaVars; - } - - private String toDecl(String id, VariableAssignments.VarType type) { - return type.getKeYDeclarationPrefix() + " " + id + ";"; - } - - /** - * Parse the declaration string for the current pattern and add the variables to the namespace - * - * @param s declaration part of a taclet - */ - public void parseDecls(String s, Services services) { - try { - KeyIO io = new KeyIO(services); - KeyAst.File ctx = ParsingFacade.parseFile(CharStreams.fromString(s)); - io.evalDeclarations(ctx); - } catch (Exception e) { - LOGGER.error("Exception while Parsing.", e); - } - } - - private Taclet parseTaclet(String s, Services services) { - KeyIO io = new KeyIO(services); - KeyAst.File ctx = ParsingFacade.parseFile(CharStreams.fromString(s)); - io.evalDeclarations(ctx); - io.evalFuncAndPred(ctx); - return io.findTaclets(ctx).get(0); - } - -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java deleted file mode 100644 index d255acb757a..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import de.uka.ilkd.key.logic.Sequent; -import de.uka.ilkd.key.proof.Node; -import de.uka.ilkd.key.proof.NodeInfo; - -/** - * Wrapper for a proof node with utilities methods to - * - * @author Sarah Grebing - * @author Alexander Weigl - */ -public class ProjectedNode { - - private final Node proofNode; - - private final ProjectedNode parent; - - /** - * Creates the wrapper object for a proof node - * - * @param node - * @param parent - */ - public ProjectedNode(Node node, ProjectedNode parent) { - this.proofNode = node; - this.parent = parent; - } - - /** - * Return the sequent of a proof node - * - * @return de.uka.ilkd.key.logic.Sequent s - */ - public Sequent getSequent() { - return proofNode.sequent(); - } - - public ProjectedNode getParent() { - return this.parent; - } - - public boolean isRoot() { - return getParent() == null; - } - - public NodeInfo getNodeInfo() { - return proofNode.getNodeInfo(); - } - - public boolean isPseudoNode() { - return proofNode == null; - } - - public Node getProofNode() { - return proofNode; - } - - public static ProjectedNode pseudoRoot() { - return new ProjectedNode(null, null); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java deleted file mode 100644 index 9a33c3a93b9..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.io.IOException; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.stream.Collectors; - -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.mgt.RuleJustification; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.rule.NoPosTacletApp; -import de.uka.ilkd.key.rule.OneStepSimplifier; -import de.uka.ilkd.key.util.MiscTools; - -import org.key_project.util.collection.ImmutableList; - -/** - * @author Alexander Weigl - * @version 1 (21.04.17) - */ -public class ProofApi { - private final KeYEnvironment env; - private final Proof proof; - - public ProofApi(Proof proof, KeYEnvironment currentEnv) { - this.proof = proof; - this.env = currentEnv; - } - - public ScriptApi getScriptApi() { - return new ScriptApi(this); - } - - /** - * Save current Proof-> ProofApi - */ - public void saveProof() throws IOException { - // TODO - } - - public KeYEnvironment getEnv() { - return env; - } - - public Proof getProof() { - return proof; - } - - public List getOpenGoals() { - ImmutableList goals = proof.openGoals(); - return goals.stream().map(g -> new ProjectedNode(g.node(), null)) - .collect(Collectors.toList()); - } - - public ProjectedNode getFirstOpenGoal() { - return getOpenGoals().get(0); - } - - public Set getRules() { - Set s = new TreeSet<>(); - Goal goal = proof.getSubtreeGoals(proof.root()).head(); - - for (final BuiltInRule br : goal.ruleAppIndex().builtInRuleAppIndex().builtInRuleIndex() - .rules()) { - s.add(br.displayName()); - } - - Set set = goal.ruleAppIndex().tacletIndex().allNoPosTacletApps(); - OneStepSimplifier simplifier = MiscTools.findOneStepSimplifier(goal.proof()); - if (simplifier != null && !simplifier.isShutdown()) { - set.addAll(simplifier.getCapturedTaclets()); - } - - for (final NoPosTacletApp app : set) { - RuleJustification just = goal.proof().mgt().getJustification(app); - if (just == null) { - continue; // do not break system because of this - } - s.add(app.taclet().displayName()); - } - - return s; - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java deleted file mode 100644 index 6ef8191acf3..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java +++ /dev/null @@ -1,129 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.logic.op.IObserverFunction; -import de.uka.ilkd.key.proof.init.ProofInputException; -import de.uka.ilkd.key.proof.init.ProofOblInput; -import de.uka.ilkd.key.speclang.Contract; -import de.uka.ilkd.key.util.KeYTypeUtil; - -import org.key_project.util.collection.ImmutableSet; - -/** - * This class serves as a facade to all functionalities that are needed for proof management, i.e., - * loading proof files, retrieving the proof obligations - * - * @author Sarah Grebing. - */ -public class ProofManagementApi { - private final KeYEnvironment currentEnv; - private final List proofContracts = new ArrayList<>(); - private HashSet ruleNames; - - public ProofManagementApi(KeYEnvironment env) { - currentEnv = env; - } - - public Services getServices() { - return currentEnv.getServices(); - } - - /** - * Retrieve a list of all available contracts - * - * @return {@link List}; can be null if no file was loaded before (we should throw an - * exception here) - */ - public List getProofContracts() { - if (proofContracts.isEmpty()) { - buildContracts(); - } - return proofContracts; - } - - /** - * constructs the possible proof contracts from the java info in the environment. - */ - private void buildContracts() { - proofContracts.clear(); - Set kjts = currentEnv.getJavaInfo().getAllKeYJavaTypes(); - for (KeYJavaType type : kjts) { - if (!KeYTypeUtil.isLibraryClass(type)) { - ImmutableSet targets = - currentEnv.getSpecificationRepository().getContractTargets(type); - for (IObserverFunction target : targets) { - ImmutableSet contracts = - currentEnv.getSpecificationRepository().getContracts(type, target); - for (Contract contract : contracts) { - proofContracts.add(contract); - } - } - } - } - } - - /** - * @param contract - * @return - * @throws ProofInputException - */ - public ProofApi startProof(ProofOblInput contract) throws ProofInputException { - return new ProofApi(currentEnv.createProof(contract), currentEnv); - } - - /** - * @param contract - * @return - * @throws ProofInputException - */ - public ProofApi startProof(Contract contract) throws ProofInputException { - return startProof(contract.createProofObl(currentEnv.getInitConfig(), contract)); - } - - public ProofApi getLoadedProof() { - return new ProofApi(currentEnv.getLoadedProof(), currentEnv); - } - - /** - * Constructs a set containing all names of a taclets that are registered in the current - * environment. - *

- * The result is cached to speed up further calls.s - * - * @return always returns a non-null hash set. - */ - public Set getRuleNames() { - if (ruleNames == null) { - ruleNames = new HashSet<>(); - currentEnv.getInitConfig().activatedTaclets() - .forEach(taclet -> ruleNames.add(taclet.displayName())); - - currentEnv.getInitConfig().builtInRules().forEach(t -> ruleNames.add(t.displayName())); - } - return ruleNames; - } - - /* - * public KeYApi.CommandType getCommandType(String identifier) { if - * (KeYApi.getMacroApi().getMacro(identifier) != null) { return KeYApi.CommandType.MACRO; } - * - * if (KeYApi.getScriptCommandApi().getScriptCommands(identifier) != null) { return - * KeYApi.CommandType.SCRIPT; } - * - * if (getRuleNames().contains(identifier)) { return KeYApi.CommandType.RULE; } - * - * return KeYApi.CommandType.UNKNOWN; } - * - * enum CommandType { SCRIPT, RULE, MACRO, UNKNOWN; } - */ -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java deleted file mode 100644 index 42c2e08f405..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java +++ /dev/null @@ -1,20 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; - -/** - * @param - * @author Alexander Weigl - */ -public class ProofScriptCommandCall { - final T parameter; - final ProofScriptCommand command; - - public ProofScriptCommandCall(ProofScriptCommand command, T arguments) { - parameter = arguments; - this.command = command; - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java deleted file mode 100644 index 7e5a8c5841b..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; - -import de.uka.ilkd.key.control.AbstractUserInterfaceControl; -import de.uka.ilkd.key.logic.Sequent; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.macros.scripts.EngineState; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; -import de.uka.ilkd.key.macros.scripts.ScriptException; -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.Node; - -import org.key_project.util.collection.ImmutableList; - -/** - * This API class offers methods to apply script commands and match commands - * - * @author Alexander Weigl - * @author S. Grebing - */ -public class ScriptApi { - private final ProofApi api; - private final EngineState state; - private final Matcher matcher; - - public ScriptApi(ProofApi proofApi) { - api = proofApi; - state = new EngineState(api.getProof()); - matcher = new Matcher(api); - } - - /** - * Matches a sequent against a sequent pattern (a schematic sequent) returns a list of Nodes - * containing matching results from where the information about instantiated schema variables - * can be extracted. If no match was possible the list is exmpt. - * - * @param pattern a string representation of the pattern sequent against which the current - * sequent should be matched - * @param currentSeq current concrete sequent - * @param assignments variables appearing in the pattern as schemavariables with their - * corresponding type in KeY - * @return List of VariableAssignments (possibly empty if no match was found) - */ - public List matchPattern(String pattern, Sequent currentSeq, - VariableAssignments assignments) { - return matcher.matchPattern(pattern, currentSeq, assignments); - } - - /** - * Execute ScriptCommand onto goal node - * - * @param call to be applied with parameters set - * @param onNode the starting node - * @return List of new proof goals (possibly empty) Should throw an Exception if command not - * applicable? - */ - public ScriptResults executeScriptCommand(ProofScriptCommandCall call, - ProjectedNode onNode) throws ScriptException, InterruptedException { - // TODO VariableAssignments should be in instantiateCommand - - state.setGoal(onNode.getProofNode()); - call.command.execute((AbstractUserInterfaceControl) api.getEnv().getUi(), call.parameter, - state); - - ImmutableList goals = api.getProof().getSubtreeGoals(onNode.getProofNode()); - // TODO filter for open goals if necessary - ScriptResults sr = new ScriptResults(); - - goals.forEach(g -> sr.add(ScriptResult.create(g.node(), onNode, call))); - - return sr; - } - - /** - * Evaluate the arguments passed to a command - * - * @param arguments - * @param - * @return - */ - public ProofScriptCommandCall instantiateCommand(ProofScriptCommand command, - Map arguments) throws Exception { - return new ProofScriptCommandCall<>(command, command.evaluateArguments(state, arguments)); - } - - - /** - * - * @param term - * @param assignments - * @return - * @throws Exception either for Syntax or Type error - */ - public Term toTerm(String term, VariableAssignments assignments) throws Exception { - // TODO - return null; - } - - /** - * ~> Beweisbaum -> Shallow Copy hier implementieren - * - * @param root - * @param end - * @return - */ - public ProjectedNode getIntermediateTree(ScriptResults root, ScriptResults end) { - /* - * Baum suche, startet bei allen Nodes von root. - * - * Endet sobald ein Node von end erreicht ist. - */ - ProjectedNode pseudoRoot = ProjectedNode.pseudoRoot(); - Queue queue = new LinkedList<>(); - root.forEach(r -> queue.add(r.getProjectedNode().getProofNode())); - - while (!queue.isEmpty()) { - - } - - - return pseudoRoot; - } - - -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java b/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java deleted file mode 100644 index b5213cb0133..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java +++ /dev/null @@ -1,114 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.List; -import java.util.Set; - -import de.uka.ilkd.key.java.PositionInfo; -import de.uka.ilkd.key.proof.Node; - -/** - * Object that represents one result goal of a script command It holds a reference to its parent - * node and to the list of variables and their values for this result Created by S. Grebing - */ -public class ScriptResult { - - /** - * The current goal node - */ - private ProjectedNode newNode; - - /** - * the parent scriptNode to which the scriptcommand was applied - */ - private ProjectedNode parentNode; - - /** - * The scriptcommand that lead to this result - */ - private ProofScriptCommandCall call; - - /** - * The reference to the variableassingments for this result - */ - // private VariableAssignments assignments; - - /** - * The list of labels for the result - */ - private Set> labels; - - /** - * List with line numbers - */ - private List linenumbers; - - // getLineNumbers hier - - /** - * - */ - ScriptResult() { - // nulls - } - - public static ScriptResult create(Node node, ProjectedNode onNode, - ProofScriptCommandCall call) { - ScriptResult sr = new ScriptResult(); - sr.parentNode = onNode; - sr.newNode = new ProjectedNode(node, onNode); - sr.call = call; - return sr; - } - - public ProjectedNode getNewNode() { - return newNode; - } - - public ScriptResult setNewNode(ProjectedNode newNode) { - this.newNode = newNode; - return this; - } - - public ProjectedNode getParentNode() { - return parentNode; - } - - public ScriptResult setParentNode(ProjectedNode parentNode) { - this.parentNode = parentNode; - return this; - } - - public ProofScriptCommandCall getCall() { - return call; - } - - public ScriptResult setCall(ProofScriptCommandCall call) { - this.call = call; - return this; - } - - public Set> getLabels() { - return labels; - } - - public ScriptResult setLabels(Set> labels) { - this.labels = labels; - return this; - } - - public List getLinenumbers() { - return linenumbers; - } - - public ScriptResult setLinenumbers(List linenumbers) { - this.linenumbers = linenumbers; - return this; - } - - public ProjectedNode getProjectedNode() { - return getNewNode(); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java b/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java deleted file mode 100644 index efc2bb66b2f..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java +++ /dev/null @@ -1,178 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Stream; - -/** - * @author Alexander Weigl - * @version 1 (21.04.17) - */ -public class ScriptResults implements List { - private final List delegated = new ArrayList<>(); - - @Override - public int size() { - return delegated.size(); - } - - @Override - public boolean isEmpty() { - return delegated.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegated.contains(o); - } - - @Override - public Iterator iterator() { - return delegated.iterator(); - } - - @Override - public Object[] toArray() { - return delegated.toArray(); - } - - @Override - public T[] toArray(T[] a) { - return delegated.toArray(a); - } - - @Override - public boolean add(ScriptResult scriptResult) { - return delegated.add(scriptResult); - } - - @Override - public boolean remove(Object o) { - return delegated.remove(o); - } - - @Override - public boolean containsAll(Collection c) { - return delegated.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - return delegated.addAll(c); - } - - @Override - public boolean addAll(int index, Collection c) { - return delegated.addAll(index, c); - } - - @Override - public boolean removeAll(Collection c) { - return delegated.removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return delegated.retainAll(c); - } - - @Override - public void replaceAll(UnaryOperator operator) { - delegated.replaceAll(operator); - } - - @Override - public void sort(Comparator c) { - delegated.sort(c); - } - - @Override - public void clear() { - delegated.clear(); - } - - @Override - public boolean equals(Object o) { - return delegated.equals(o); - } - - @Override - public int hashCode() { - return delegated.hashCode(); - } - - @Override - public ScriptResult get(int index) { - return delegated.get(index); - } - - @Override - public ScriptResult set(int index, ScriptResult element) { - return delegated.set(index, element); - } - - @Override - public void add(int index, ScriptResult element) { - delegated.add(index, element); - } - - @Override - public ScriptResult remove(int index) { - return delegated.remove(index); - } - - @Override - public int indexOf(Object o) { - return delegated.indexOf(o); - } - - @Override - public int lastIndexOf(Object o) { - return delegated.lastIndexOf(o); - } - - @Override - public ListIterator listIterator() { - return delegated.listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - return delegated.listIterator(index); - } - - @Override - public List subList(int fromIndex, int toIndex) { - return delegated.subList(fromIndex, toIndex); - } - - @Override - public Spliterator spliterator() { - return delegated.spliterator(); - } - - @Override - public boolean removeIf(Predicate filter) { - return delegated.removeIf(filter); - } - - @Override - public Stream stream() { - return delegated.stream(); - } - - @Override - public Stream parallelStream() { - return delegated.parallelStream(); - } - - @Override - public void forEach(Consumer action) { - delegated.forEach(action); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java b/key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java deleted file mode 100644 index bf08e9862ac..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import de.uka.ilkd.key.logic.SequentFormula; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.rule.MatchConditions; -import de.uka.ilkd.key.rule.inst.SVInstantiations; - -/** - * Created by sarah on 5/2/17. - */ -public final class SearchNode { - private final SequentFormula[] pattern; - private final int pos; - private final int succAntPos; - private final MatchConditions mc; - - - public SearchNode(SequentFormula[] pattern, int succAntPos) { - this.pattern = pattern; - this.pos = 0; - this.succAntPos = succAntPos; - this.mc = MatchConditions.EMPTY_MATCHCONDITIONS; - } - - public SearchNode(SearchNode parent, MatchConditions cond) { - this.pattern = parent.pattern; - this.succAntPos = parent.succAntPos; - int parentPos = parent.pos; - this.pos = parentPos + 1; - mc = cond; - } - - public boolean isAntecedent() { - return pos < succAntPos; - } - - public Term getPatternTerm() { - return pattern[pos].formula(); - } - - public boolean isFinished() { - return pos >= pattern.length; - } - - public SVInstantiations getInstantiations() { - return mc == null ? null : mc.getInstantiations(); - } - - public MatchConditions getMatchConditions() { - return mc; - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java b/key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java deleted file mode 100644 index 6f2fee63133..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.HashMap; -import java.util.Map; - -/** - * Class to represent current Variable assigments. Created by S.Grebing - */ -public class VariableAssignments { - - - public enum VarType { - INT("\\term int"), BOOL("\\term bool"), ANY("\\term any"), INT_ARRAY("\\term int[]"), - OBJECT("\\term Object"), HEAP("\\term Heap"), FIELD("\\term Field"), - LOCSET("\\term LocSet"), FORMULA("\\formula"), SEQ("\\term Seq"); - - private final String declPrefix; - - VarType(String declPrefix) { - this.declPrefix = declPrefix; - } - - public String getKeYDeclarationPrefix() { - return declPrefix; - } - } - - /** - * Reference to parent assignments - */ - private final VariableAssignments parent; - - /** - * Current Assignments - */ - private final Map currentAssignments; - - /** - * Type Map of assignments - */ - private final Map typeMap; - - /** - * Create new, empty variable assignment, to add variables - * - * @param parentAssignments the parent assignments - */ - public VariableAssignments(VariableAssignments parentAssignments) { - this.currentAssignments = new HashMap<>(); - this.typeMap = new HashMap<>(); - this.parent = parentAssignments; - } - - - /** - * Default constructor - */ - public VariableAssignments() { - this.currentAssignments = new HashMap<>(); - this.typeMap = new HashMap<>(); - this.parent = null; - } - - - /** - * Get the value of a stored variable name TODO Exception spezifischer - * - * @param varName - * @return Value of variable - */ - public Object getVarValue(String varName) throws Exception { - if (currentAssignments.containsKey(varName)) { - return currentAssignments.get(varName); - } else { - if (parent != null) { - return parent.getVarValue(varName); - } else { - throw new Exception("Variable " + varName + " could not be found"); - } - } - } - - /** - * Add a variable assignment with type and value - * - * @param varName - * @param value - * @param type - */ - public void addAssignmentWithType(String varName, Object value, VarType type) { - typeMap.put(varName, type); - currentAssignments.put(varName, value); - - } - - /** - * Add a variable assignment without type - * - * @param varName - * @param value - */ - public void addAssignment(String varName, Object value) throws Exception { - if (typeMap.containsKey(varName)) { - currentAssignments.put(varName, value); - } else { - throw new Exception("Variable " + varName + "must be declared first"); - } - - } - - /** - * TODO better exception Add a new type declaration - * - * @param varName - * @param type - */ - public void addType(String varName, VarType type) throws Exception { - if (typeMap.containsKey(varName)) { - if (typeMap.get(varName) != type) { - throw new Exception("Variable " + varName + "was already declared with type " - + typeMap.get(varName).toString()); - } - } else { - typeMap.put(varName, type); - } - } - - /** - * Returns the map of ID -> Type mappings - * - * @return - */ - public Map getTypeMap() { - return this.typeMap; - } - - - /* - * public Object getValue(String name) { return null; } - * - * public Type getType() { return null; } - * - * public void setType(Type type) { - * - * } - * - * public void setValue(String name) { - * - * } - */ -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/package-info.java b/key.core/src/main/java/de/uka/ilkd/key/api/package-info.java deleted file mode 100644 index 402b65aa83c..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This package gives an high-level entry point to the KeY world. - * - * @author Alexander Weigl - * @author Sarah Grebing - * @version 1 (21.04.17) - * @see de.uka.ilkd.key.api.KeYApi - */ -package de.uka.ilkd.key.api; diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java index 370527fb280..dc2936d64e7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java @@ -3,13 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.control; -import java.io.File; -import java.util.List; -import java.util.Properties; -import java.util.function.Consumer; - import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.op.IObserverFunction; import de.uka.ilkd.key.parser.Location; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.init.InitConfig; @@ -20,7 +17,15 @@ import de.uka.ilkd.key.proof.io.AbstractProblemLoader.ReplayResult; import de.uka.ilkd.key.proof.io.ProblemLoaderException; import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.rule.Rule; +import de.uka.ilkd.key.speclang.Contract; +import de.uka.ilkd.key.util.KeYTypeUtil; import de.uka.ilkd.key.util.Pair; +import org.key_project.util.collection.ImmutableSet; + +import java.io.File; +import java.util.*; +import java.util.function.Consumer; /** * Instances of this class are used to collect and access all relevant information for verification @@ -62,7 +67,7 @@ public class KeYEnvironment { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig) { @@ -72,11 +77,11 @@ public KeYEnvironment(U ui, InitConfig initConfig) { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig, Proof loadedProof, - Pair proofScript, ReplayResult replayResult) { + Pair proofScript, ReplayResult replayResult) { this.ui = ui; this.initConfig = initConfig; this.loadedProof = loadedProof; @@ -175,15 +180,15 @@ public Proof createProof(ProofOblInput input) throws ProofInputException { * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. + * @param location The location to load. + * @param classPaths The class path entries to use. * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param includes Optional includes to consider. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes) + List classPaths, File bootClassPath, List includes) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, false); } @@ -192,103 +197,103 @@ public static KeYEnvironment load(File location, * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes, - RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, null, - ruleCompletionHandler, false); + ruleCompletionHandler, false); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as - * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file - * will be used for new proofs. + * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file + * will be used for new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, null, null, - forceNewProfileOfNewProofs); + forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, poPropertiesToForce, - ruleCompletionHandler, - null, forceNewProfileOfNewProofs); + ruleCompletionHandler, + null, forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. - * @param callbackProofLoaded An optional callback (called when the proof is loaded, before - * replay) + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param callbackProofLoaded An optional callback (called when the proof is loaded, before + * replay) * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - Consumer callbackProofLoaded, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + Consumer callbackProofLoaded, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { DefaultUserInterfaceControl ui = new DefaultUserInterfaceControl(ruleCompletionHandler); AbstractProblemLoader loader = ui.load(profile, location, classPaths, bootClassPath, - includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); + includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); InitConfig initConfig = loader.getInitConfig(); return new KeYEnvironment<>(ui, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); } public static KeYEnvironment load(File keyFile) @@ -319,4 +324,41 @@ public boolean isDisposed() { public Pair getProofScript() { return proofScript; } + + /** + * Retrieve a list of all available contracts for all known Java types. + * + * @return a non-null list, possible empty + */ + public List getAvailableContracts() { + List proofContracts = new ArrayList<>(512); + Set kjts = getJavaInfo().getAllKeYJavaTypes(); + for (KeYJavaType type : kjts) { + if (!KeYTypeUtil.isLibraryClass(type)) { + ImmutableSet targets = getSpecificationRepository().getContractTargets(type); + for (IObserverFunction target : targets) { + ImmutableSet contracts = getSpecificationRepository().getContracts(type, target); + for (Contract contract : contracts) { + proofContracts.add(contract); + } + } + } + } + return proofContracts; + } + + + /** + * Constructs a list containing all known rules that are registered in the current + * environment. + * + * @return always returns a non-null list + */ + public List getRules() { + var rules = new ArrayList(4096); + rules.addAll(getInitConfig().activatedTaclets()); + getInitConfig().builtInRules().forEach(rules::add); + return rules; + } + } diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofMacroApi.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java similarity index 83% rename from key.core/src/main/java/de/uka/ilkd/key/api/ProofMacroApi.java rename to key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java index fbdf19d343d..29b9579f640 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofMacroApi.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java @@ -1,25 +1,30 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; +package de.uka.ilkd.key.macros; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; -import de.uka.ilkd.key.macros.ProofMacro; - /** * This class provides access to the proof script commands. * * @author Alexander Weigl * @version 1 (09.05.17) */ -public class ProofMacroApi { +public class ProofMacroFacade { + private static ProofMacroFacade INSTANCE; + + public static ProofMacroFacade instance() { + if (INSTANCE == null) INSTANCE = new ProofMacroFacade(); + return INSTANCE; + } + private final Map commandMap = new HashMap<>(); - public ProofMacroApi() { + public ProofMacroFacade() { initialize(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandApi.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java similarity index 79% rename from key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandApi.java rename to key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java index bd23b64bc18..44a26161832 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandApi.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java @@ -1,28 +1,34 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; +package de.uka.ilkd.key.macros.scripts; + +import de.uka.ilkd.key.smt.IllegalNumberException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; - /** * This class provides access to the proof script commands. * * @author Alexander Weigl * @version 1 (21.04.17) */ -public class ProofScriptCommandApi { +public class ProofScriptCommandFacade { + private static ProofScriptCommandFacade INSTANCE; private final Map> commandMap = new HashMap<>(); - public ProofScriptCommandApi() { + public ProofScriptCommandFacade() { initialize(); } + public static ProofScriptCommandFacade instance() { + if(INSTANCE == null) INSTANCE = new ProofScriptCommandFacade(); + return INSTANCE; + } + @SuppressWarnings("rawtypes") private void initialize() { ServiceLoader loader = ServiceLoader.load(ProofScriptCommand.class); diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java index b86a6a47719..6198a8b88d9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java @@ -3,10 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.proof; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicLong; import de.uka.ilkd.key.java.Services; @@ -16,6 +13,7 @@ import de.uka.ilkd.key.logic.op.ProgramVariable; import de.uka.ilkd.key.pp.LogicPrinter; import de.uka.ilkd.key.pp.NotationInfo; +import de.uka.ilkd.key.proof.mgt.RuleJustification; import de.uka.ilkd.key.proof.proofevent.NodeChangeJournal; import de.uka.ilkd.key.proof.proofevent.RuleAppInfo; import de.uka.ilkd.key.proof.rulefilter.TacletFilter; @@ -26,6 +24,7 @@ import de.uka.ilkd.key.strategy.AutomatedRuleApplicationManager; import de.uka.ilkd.key.strategy.QueueRuleApplicationManager; import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.util.MiscTools; import de.uka.ilkd.key.util.properties.MapProperties; import de.uka.ilkd.key.util.properties.Properties; import de.uka.ilkd.key.util.properties.Properties.Property; @@ -716,6 +715,13 @@ public List getAllBuiltInRuleApps() { return ruleApps; } + /** + * Return a list with available taclet application on this goal. + */ + public List getAllTacletApps() { + return getAllTacletApps(proof().getServices()); + } + public List getAllTacletApps(Services services) { RuleAppIndex index = ruleAppIndex(); index.autoModeStopped(); @@ -740,4 +746,37 @@ protected boolean filter(Taclet taclet) { return allApps; } + /** + * Returns a list with all known rule applications within this proof goal. + */ + public List getAllAvailableRules() { + var taclets = getAllTacletApps(); + var builtin = getAllBuiltInRuleApps(); + builtin.addAll(taclets); + return builtin; + } + + public List getAvailableRules() { + var s = new ArrayList(2048); + for (final BuiltInRule br : ruleAppIndex().builtInRuleAppIndex() + .builtInRuleIndex().rules()) { + s.add(br); + } + + Set set = ruleAppIndex().tacletIndex().allNoPosTacletApps(); + OneStepSimplifier simplifier = MiscTools.findOneStepSimplifier(proof()); + if (simplifier != null && !simplifier.isShutdown()) { + set.addAll(simplifier.getCapturedTaclets()); + } + + for (final NoPosTacletApp app : set) { + RuleJustification just = proof().mgt().getJustification(app); + if (just == null) { + continue; // do not break system because of this + } + s.add(app.taclet()); //TODO not good + } + return s; + } + } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java index 6b97d88d82d..d7ac6c484d0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java @@ -11,6 +11,7 @@ import java.util.function.Predicate; import javax.swing.*; +import de.uka.ilkd.key.Identifiable; import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.*; @@ -27,6 +28,7 @@ import de.uka.ilkd.key.proof.replay.CopyingProofReplayer; import de.uka.ilkd.key.rule.NoPosTacletApp; import de.uka.ilkd.key.rule.OneStepSimplifier; +import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.merge.MergePartner; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.rule.merge.MergeRuleBuiltInRuleApp; @@ -54,7 +56,7 @@ * information, and methods to apply rules. Furthermore, it offers services that deliver the open * goals, namespaces and several other information about the current state of the proof. */ -public class Proof implements Named { +public class Proof implements Named, Identifiable { /** * The time when the {@link Proof} instance was created. @@ -1475,4 +1477,12 @@ public void copyCachedGoals(Proof referencedFrom, Consumer callbackTota } } } + + /** + * {@inheritDoc} + */ + @Override + public String identification() { + return getClass().getName() + "_" + name + "_" + hashCode(); + } } diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java index 3561874cf37..21f2fbc3674 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java @@ -3,47 +3,32 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.speclang.njml; -import java.io.File; - -import de.uka.ilkd.key.api.KeYApi; -import de.uka.ilkd.key.api.ProofManagementApi; -import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.control.KeYEnvironment; 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.util.HelperClassForTests; - import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.File; +import java.util.stream.Stream; public class ContractLoadingTests { public static final File EXAMPLES_DIR = new File("../key.ui/examples/"); - @Test - public void sumAndMax() throws ProblemLoaderException { - final File javaFile = - new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Services services = file.getServices(); - Logger LOGGER = LoggerFactory.getLogger(ContractLoadingTests.class); - for (Contract proofContract : file.getProofContracts()) { - LOGGER.info(proofContract.getPlainText(services)); - } + static Stream files() { + return Stream.of( + new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java") + ).map(Arguments::of); } - @Test - public void issues1658() throws ProblemLoaderException { - final File javaFile = - new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"); - Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); - } - - @Test + @ParameterizedTest + @MethodSource("files") void issues1717() throws ProblemLoaderException, ProofInputException { File javaFile = new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1717/UnderscoreZero.java"); @@ -55,20 +40,8 @@ void issues1717() throws ProblemLoaderException, ProofInputException { } @Test - public void specMathJavaMathTest() throws ProblemLoaderException { - final File javaFile = - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"); - Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); - } - - @Test - public void specMathBigintMathTest() throws ProblemLoaderException { - final File javaFile = - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java"); - Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); + public void nonEmptyContract(File javaFile) throws ProblemLoaderException { + KeYEnvironment env = KeYEnvironment.load(javaFile); + Assertions.assertFalse(env.getAvailableContracts().isEmpty()); } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java index e37603b344e..16420583f3a 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java @@ -301,7 +301,7 @@ public static List listExamples(File examplesDir) { new BufferedReader(new FileReader(index, StandardCharsets.UTF_8))) { while ((line = br.readLine()) != null) { line = line.trim(); - if (line.startsWith("#") || line.length() == 0) { + if (line.startsWith("#") || line.isEmpty()) { continue; } File f = new File(examplesDir, line); diff --git a/keyext.api.doc/build.gradle b/keyext.api.doc/build.gradle new file mode 100644 index 00000000000..f7aadd6467c --- /dev/null +++ b/keyext.api.doc/build.gradle @@ -0,0 +1,4 @@ +dependencies { + implementation("com.github.javaparser:javaparser-core:3.25.5") + implementation("com.github.javaparser:javaparser-symbol-solver-core:3.25.5") +} \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java new file mode 100644 index 00000000000..a9df59adef8 --- /dev/null +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -0,0 +1,162 @@ +import com.github.javaparser.ParseResult; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.TypeDeclaration; +import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; +import com.github.javaparser.javadoc.JavadocBlockTag; +import com.github.javaparser.resolution.SymbolResolver; +import com.github.javaparser.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.TypeSolverBuilder; +import com.github.javaparser.utils.SourceRoot; + +import javax.annotation.Nonnull; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +public class ExtractMetaData { + private static PrintWriter out; + + public static void main(String[] args) throws IOException { + System.out.println("XXX" + Arrays.toString(args)); + ParserConfiguration config = new ParserConfiguration(); + config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); + /*config.setAttributeComments(true); + config.setLexicalPreservationEnabled(false); + config.setStoreTokens(false); + config.setIgnoreAnnotationsWhenAttributingComments(true); + config.setDoNotAssignCommentsPrecedingEmptyLines(true);*/ + //var root = Paths.get(args[0]); + TypeSolver typeSolver = new TypeSolverBuilder() + .withSourceCode("keyext.api/src/main/java") + .withSourceCode("key.core/src/main/java") + .withSourceCode("key.util/src/main/java") + .withCurrentJRE() + .build(); + SymbolResolver symbolResolver = new JavaSymbolSolver(typeSolver); + config.setSymbolResolver(symbolResolver); + var source = new SourceRoot(Paths.get("keyext.api", "src", "main", "java"), config); + var cu = source.tryToParse(); + var jsonSegment = Comparator.comparing(ExtractMetaData::getJsonSegment); + var segments = cu.stream().filter(ParseResult::isSuccessful) + .filter(it -> it.getResult().get().getPrimaryType().isPresent()) + .map(it -> it.getResult().get().getPrimaryType().get()) + .filter(ExtractMetaData::hasJsonSegment) + .sorted(jsonSegment) + .toList(); + + try (var out = new PrintWriter(new FileWriter("doc.md"))) { + ExtractMetaData.out = out; + printHeader(segments); + segments.forEach(ExtractMetaData::printDocumentation); + printFooter(segments); + } + + // "org.keyproject.key.api.remoteapi.KeyApi"; + } + + private static void printDocumentation(TypeDeclaration typeDeclaration) { + out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); + out.println(getJavaDoc(typeDeclaration)); + out.println("\n"); + + for (MethodDeclaration method : typeDeclaration.getMethods()) { + if (!isExported(method)) continue; + + String callName = getCallName(method, typeDeclaration); + + out.format("### %s (type: %s) %n%n", callName, type(method)); + + out.println(getJavaDoc(method)); + + out.println(); + } + } + + private static String getCallName(MethodDeclaration m, TypeDeclaration td) { + var annotationExpr = m.getAnnotationByName("JsonNotification").or( + () -> m.getAnnotationByName("JsonRequest")) + .orElseThrow(); + + var segment = getJsonSegment(td) + "/"; + String name = ""; + + if (annotationExpr.isMarkerAnnotationExpr()) { + name = m.getNameAsString(); + } else if (annotationExpr.isSingleMemberAnnotationExpr()) { + var sma = annotationExpr.asSingleMemberAnnotationExpr(); + name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); + } else { + var ne = annotationExpr.asNormalAnnotationExpr(); + for (MemberValuePair pair : ne.getPairs()) { + switch (pair.getName().asString()) { + case "value": + name = pair.getValue().asLiteralStringValueExpr().getValue(); + break; + case "useSegment": + if (!pair.getValue().asBooleanLiteralExpr().getValue()) { + segment = ""; + } + } + } + } + return segment + name; + } + + + @Nonnull + private static String getJavaDoc(NodeWithJavadoc typeDeclaration) { + if (typeDeclaration.getJavadoc().isPresent()) { + final var javadoc = typeDeclaration.getJavadoc().get(); + return javadoc.getDescription().toText() + + "\n\n" + + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) + .collect(Collectors.joining("\n")); + } + return ""; + } + + private static String type(MethodDeclaration method) { + if (method.getAnnotationByName("JsonNotification").isPresent()) + return "notification"; + if (method.getAnnotationByName("JsonRequest").isPresent()) + return "request"; + return ""; + } + + private static boolean isExported(MethodDeclaration method) { + return method.getAnnotationByName("JsonNotification").isPresent() + || method.getAnnotationByName("JsonRequest").isPresent(); + } + + private static void printHeader(List> segments) { + out.format("# KeY-API%n%n"); + } + + private static void printFooter(List> segments) { + + + } + + + private static boolean hasJsonSegment(TypeDeclaration it) { + return it.getAnnotationByName("JsonSegment").isPresent(); + } + + private static String getJsonSegment(TypeDeclaration it) { + var ae = it.getAnnotationByName("JsonSegment").get(); + return ae.asSingleMemberAnnotationExpr().getMemberValue() + .asLiteralStringValueExpr().getValue(); + } +} diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index 0f3b2743c24..c2b84249430 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -18,6 +18,9 @@ dependencies { implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") implementation("org.eclipse.jetty.websocket:websocket-javax-server:10.0.16") implementation("info.picocli:picocli:4.7.5") + + implementation("com.google.guava:guava:32.1.3-jre") + //for GraalVM annotationProcessor 'info.picocli:picocli-codegen:4.7.5' } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java deleted file mode 100644 index 9c03fdfae41..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.keyproject.key.api; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - -import java.io.File; -import java.io.IOException; - -public class FileTypeAdapter extends TypeAdapter { - @Override - public void write(JsonWriter out, File value) throws IOException { - out.value(value.toString()); - } - - @Override - public File read(JsonReader in) throws IOException { - return new File(in.nextString()); - } -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java new file mode 100644 index 00000000000..248210a9f7f --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -0,0 +1,168 @@ +package org.keyproject.key.api; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.gui.Example; +import de.uka.ilkd.key.gui.ExampleChooser; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.macros.ProofMacro; +import de.uka.ilkd.key.macros.ProofMacroFacade; +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import de.uka.ilkd.key.macros.scripts.ProofScriptCommandFacade; +import de.uka.ilkd.key.proof.Node; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.Statistics; +import de.uka.ilkd.key.util.KeYConstants; +import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.keyproject.key.api.adapters.KeyAdapter; +import org.keyproject.key.api.data.*; +import org.keyproject.key.api.remoteapi.KeyApi; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public record KeyApiImpl(KeyAdapter adapter) implements KeyApi { + + @Override + @JsonRequest + public CompletableFuture> examples() { + return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); + } + + @Override + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(null); + } + + @Override + public void exit() { + } + + @Override + public void setTrace(SetTraceParams params) { + + } + + @Override + public CompletableFuture getVersion() { + return CompletableFuture.completedFuture(KeYConstants.VERSION); + } + + @Override + public CompletableFuture> getAvailableMacros() { + return CompletableFuture.completedFuture( + ProofMacroFacade.instance().getMacros().stream().toList() + ); + } + + @Override + public CompletableFuture>> getAvailableScriptCommands() { + return CompletableFuture.completedFuture( + ProofScriptCommandFacade.instance().getScriptCommands().stream().toList()); + } + + @Override + public CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options) { + return null; + } + + @Override + public CompletableFuture macro(Proof id, String macroId, StreategyOptions options) { + return null; + } + + @Override + public CompletableFuture auto(Proof id, StreategyOptions options) { + return null; + } + + @Override + public CompletableFuture dispose(Proof id) { + return null; + } + + @Override + public CompletableFuture goals(Proof id) { + return null; + } + + @Override + public CompletableFuture tree(Proof proof) { + return null; + } + + @Override + public CompletableFuture root(Proof proof) { + return null; + } + + @Override + public CompletableFuture> children(Proof proof, Node nodeId) { + return null; + } + + @Override + public CompletableFuture> pruneTo(Proof proof, Node nodeId) { + return null; + } + + @Override + public CompletableFuture statistics(Proof proof) { + return null; + } + + @Override + public CompletableFuture treeRoot(Proof proof) { + return null; + } + + @Override + public CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId) { + return null; + } + + @Override + public CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId) { + return null; + } + + @Override + public CompletableFuture> sorts(KeYEnvironment env) { + return null; + } + + @Override + public CompletableFuture> functions(KeYEnvironment env) { + return null; + } + + @Override + public CompletableFuture> contracts(KeYEnvironment env) { + return null; + } + + @Override + public CompletableFuture openContract(KeYEnvironment env, String contractId) { + return null; + } + + @Override + public CompletableFuture print(Node id) { + return null; + } + + @Override + public CompletableFuture> actions(PrintId id, int pos) { + return null; + } + + @Override + public CompletableFuture> applyAction(TermActionId id) { + return null; + } + + @Override + public void freePrint(PrintId id) { + + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index 26837bb84b6..408cc36acdd 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -4,7 +4,7 @@ import com.google.gson.GsonBuilder; import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.websocket.jakarta.WebSocketLauncherBuilder; -import org.keyproject.key.api.remoteapi.KeyApiImpl; +import org.keyproject.key.api.adapters.KeyAdapter; import org.keyproject.key.api.remoteclient.ClientApi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,9 +16,6 @@ import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.concurrent.ExecutionException; /** @@ -29,6 +26,8 @@ public class StartServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); + private static KeyAdapter adapter; + //region CLI arguments @Option(names = "--std", description = "use stdout and stdin for communication") boolean stdStreams; @@ -55,7 +54,7 @@ public class StartServer implements Runnable { boolean helpRequested = false; @Option(names = "--websocket") - boolean websocket; + boolean websocket = false; //endregion public static void main(String[] args) { @@ -115,27 +114,6 @@ public void run() { return; } - /* - var server = new Server(); - var connector = new ServerConnector(); - server.addConnector(connector); - // Setup the basic application "context" for this application at "/" - // This is also known as the handler tree (in jetty speak) - var context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/"); - server.setHandler(context); - - // Initialize javax.websocket layer - JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> - { - // Configure defaults for container - wsContainer.setDefaultMaxTextMessageBufferSize(65535); - - // Add WebSocket endpoint to javax.websocket layer - wsContainer.addEndpoint(WebSocketEndpoint.class); - });*/ - - try { if (websocket) { var launcherBuilder = new WebSocketLauncherBuilder() @@ -144,7 +122,7 @@ public void run() { .traceMessages(new PrintWriter(System.err)) .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - launcherBuilder.setLocalService(new KeyApiImpl()); + launcherBuilder.setLocalService(new KeyApiImpl(adapter)); launcherBuilder.setRemoteInterface(ClientApi.class); launcherBuilder.create().startListening().get(); } else { @@ -160,8 +138,9 @@ public void run() { } } + public static void configureJson(GsonBuilder gsonBuilder) { - gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); + adapter = new KeyAdapter(gsonBuilder); } public static Launcher launch(OutputStream out, InputStream in) { @@ -174,30 +153,11 @@ public static Launcher launch(OutputStream out, InputStream in) { .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - //if (localServices != null && !localServices.isEmpty()) - launcherBuilder.setLocalService(new KeyApiImpl()); + launcherBuilder.setLocalService(new KeyApiImpl(adapter)); //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) launcherBuilder.setRemoteInterface(ClientApi.class); return launcherBuilder.create(); } - - - private static Collection> getRemoteInterfaces() { - return Collections.singleton(ClientApi.class); - /* return ServiceLoader.load(ClientService.class) - .stream() - .map(ServiceLoader.Provider::type) - .collect(Collectors.toSet()); - */ - } - - private static List getLocalServices() { - return Collections.singletonList(new KeyApiImpl()); - /*return ServiceLoader.load(KeyService.class) - .stream().map(ServiceLoader.Provider::get) - .map(it -> (Object) it) - .toList();*/ - } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java new file mode 100644 index 00000000000..9168a2128f5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -0,0 +1,96 @@ +package org.keyproject.key.api.adapters; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.gson.*; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import de.uka.ilkd.key.Identifiable; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.macros.ProofMacro; +import de.uka.ilkd.key.macros.ProofMacroFacade; +import de.uka.ilkd.key.proof.Proof; +import org.keyproject.key.api.data.MacroDescription; + +import java.io.File; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.lang.reflect.Type; + +/** + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +public class KeyAdapter { + private final BiMap> map = HashBiMap.create(1024); + //private final TypeAdapter adaptor; + + public KeyAdapter(GsonBuilder gson) { + gson.registerTypeAdapter(File.class, new FileTypeAdapter()); + gson.registerTypeAdapter(Function.class, new FunctionTypeAdapter()); + gson.registerTypeAdapter(Proof.class, new IdentifiableTypeAdapter()); + gson.registerTypeAdapter(ProofMacro.class, new MacroTypeAdapter()); + //adaptor = gson.create().getAdapter(Object.class); + } + + + //translating entities to identification strings + public String insert(Identifiable p) { + var id = p.identification(); + if (!map.containsKey(id)) { + map.put(id, new WeakReference<>(p)); + } + return id; + } + + public Object find(String id) { + return map.get(id).get(); + } + //endregion + + class MacroTypeAdapter implements JsonSerializer { + @Override + public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationContext context) { + return context.serialize(MacroDescription.from(src)); + } + } + + class FileTypeAdapter extends TypeAdapter { + @Override + public void write(JsonWriter out, File value) throws IOException { + out.value(value.toString()); + } + + @Override + public File read(JsonReader in) throws IOException { + return new File(in.nextString()); + } + } + + class FunctionTypeAdapter implements JsonSerializer { + @Override + public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationContext context) { + var obj = new JsonObject(); + obj.add("name", context.serialize(src.name().toString())); + obj.add("skolemConstant", context.serialize(src.isSkolemConstant())); + obj.add("isRigid", context.serialize(src.isRigid())); + obj.add("isUnique", context.serialize(src.isUnique())); + obj.add("sort", context.serialize(src.sort())); + obj.add("argSorts", context.serialize(src.argSorts())); + return obj; + } + } + + class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { + @Override + public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return (Identifiable) find(json.getAsString()); + } + + @Override + public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerializationContext context) { + insert(src); + return context.serialize(src.identification()); + } + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java new file mode 100644 index 00000000000..bbc28eec1ec --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java @@ -0,0 +1,7 @@ +/** + * Adapter classes for translating things from Java to JSON via GSON api. + * + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +package org.keyproject.key.api.adapters; \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java new file mode 100644 index 00000000000..a81f8d863db --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record ContractDesc() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java new file mode 100644 index 00000000000..0c612b44cc2 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api.data; + +import java.util.List; + +/** + * @author Alexander Weigl + * @version 1 (15.10.23) + */ +public record FunctionDesc(String name, String sort, List sorts) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java b/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java new file mode 100644 index 00000000000..7a0e2f264e0 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.pp.PositionTable; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record GoalText(PrintId id, String text, PositionTable table) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java new file mode 100644 index 00000000000..85ec900cd57 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java @@ -0,0 +1,14 @@ +package org.keyproject.key.api.data; + +import java.io.File; +import java.util.List; + +/** + * + * @param keyFile + * @param javaFile + * @param classPath + * @param bootClassPath + * @param includes + */ +public record LoadParams(File keyFile, File javaFile, List classPath, File bootClassPath, List includes) {} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java similarity index 72% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java rename to keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java index ad6d12babf8..0274bc38b30 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java @@ -1,7 +1,13 @@ -package org.keyproject.key.api.remoteapi; +package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacro; +/** + * + * @param name + * @param description + * @param category + */ public record MacroDescription(String name, String description, String category) { public static MacroDescription from(ProofMacro m) { return new MacroDescription(m.getName(), m.getDescription(), m.getCategory()); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java new file mode 100644 index 00000000000..74c2d9d1cc4 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record MacroStatistic() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java new file mode 100644 index 00000000000..9bc8ad0cd04 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record NodeDesc() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java new file mode 100644 index 00000000000..640c25371d6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (15.10.23) + */ +public record PredicateDesc(String name, String[] argSorts) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java new file mode 100644 index 00000000000..3d4893d43e4 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record PrintId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java new file mode 100644 index 00000000000..4e2de0d4010 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java @@ -0,0 +1,18 @@ +package org.keyproject.key.api.data; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +/** + * @author Alexander Weigl + * @version 1 (15.10.23) + */ +public record ProblemDefinition( + @Nullable List sorts, + @Nullable List functions, + @Nullable List predicates, + @Nullable List antecTerms, + @Nullable List succTerms +) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java new file mode 100644 index 00000000000..14d737fd5d6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java @@ -0,0 +1,42 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.concurrent.CompletableFuture; + +/** + * Functionalities for loading proofs either from a built-in example, or from a set of files. + * + * @author Alexander Weigl + * @since v1 + */ +@JsonSegment("loading") +public interface ProofLoading { + /** + * I am not sure whether this is helpful. Mainly a feature for testing?! + * @param id + * @return + */ + @JsonRequest + CompletableFuture loadExample(String id); + + /** + * + */ + @JsonRequest + CompletableFuture loadProblem(ProblemDefinition problem); + + /** + * Test! + * + * @param params parameters for loading + * @return + * @throws ProblemLoaderException if something went wrong + */ + @JsonRequest + CompletableFuture> load(LoadParams params) throws ProblemLoaderException; +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java new file mode 100644 index 00000000000..b582b4a73f5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record SortDesc() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java new file mode 100644 index 00000000000..b73ee35b7b5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record StreategyOptions() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java new file mode 100644 index 00000000000..b69046120f5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TermAction(TermActionId commandId, String displayName) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java new file mode 100644 index 00000000000..7951c776af4 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TermActionId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java similarity index 54% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java rename to keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java index 567b740d6d8..7f8c9564aa9 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java @@ -1,4 +1,4 @@ -package org.keyproject.key.api.remoteapi; +package org.keyproject.key.api.data; public enum TraceValue { Off, Message, All; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java new file mode 100644 index 00000000000..213bb6b9dbe --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public class TreeNodeDesc { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java new file mode 100644 index 00000000000..3dba5cc492e --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TreeNodeId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java new file mode 100644 index 00000000000..e82ca44ae28 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java @@ -0,0 +1,31 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.proof.Proof; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.ContractDesc; +import org.keyproject.key.api.data.SortDesc; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("env") +public interface EnvApi { + @JsonRequest + CompletableFuture> sorts(KeYEnvironment env); + + @JsonRequest + CompletableFuture> functions(KeYEnvironment env); + + @JsonRequest + CompletableFuture> contracts(KeYEnvironment env); + + @JsonRequest + CompletableFuture openContract(KeYEnvironment env, String contractId); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java deleted file mode 100644 index 3a2b5291d66..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -/** - * @author Alexander Weigl - * @version 1 (06.10.23) - */ -public record EnvId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java similarity index 91% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java index b1bc064b954..9ccbb03049f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java @@ -8,7 +8,7 @@ import java.util.concurrent.CompletableFuture; @JsonSegment("examples") -public interface KeyExampleApi { +public interface ExampleApi { @JsonRequest("list") CompletableFuture> examples(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java new file mode 100644 index 00000000000..fe678b8f04e --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -0,0 +1,32 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.Node; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.GoalText; +import org.keyproject.key.api.data.PrintId; +import org.keyproject.key.api.data.TermAction; +import org.keyproject.key.api.data.TermActionId; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("goal") +public interface GoalApi { + @JsonRequest + CompletableFuture print(Node id); + + @JsonRequest + CompletableFuture> actions(PrintId id, int pos); + + @JsonRequest("apply_action") + CompletableFuture> applyAction(TermActionId id); + + @JsonNotification("free") + void freePrint(PrintId id); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index 9a6e35fe2eb..ac650359a74 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -1,55 +1,7 @@ package org.keyproject.key.api.remoteapi; -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; - -import java.util.concurrent.CompletableFuture; - -public interface KeyApi extends KeyExampleApi, KeyMetaApi { - //region general server management - /** - * Shutdown Request (:leftwards_arrow_with_hook:) - The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. - - If a server receives requests after a shutdown request those requests should error with InvalidRequest. - - Request: - - method: ‘shutdown’ - params: none - Response: - - result: null - error: code and message set in case an exception happens during shutdown request. - */ - @JsonRequest - CompletableFuture shutdown(); - - /** - * Exit Notification (:arrow_right:) - * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. - *

- * Notification: - *

- * method: ‘exit’ - * params: none - */ - @JsonNotification - void exit(); - - - - interface SetTraceParams { - /** - * The new value that should be assigned to the trace setting. - */ - TraceValue value = null; - } - /** - * SetTrace Notification - * A notification that should be used by the client to modify the trace setting of the server. - */ - @JsonNotification - void setTrace(SetTraceParams params); - //endregion +/** + * The combined interface that is provided by KeY. + */ +public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi { } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java deleted file mode 100644 index 33ae9c03aba..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -import de.uka.ilkd.key.api.KeYApi; -import de.uka.ilkd.key.gui.Example; -import de.uka.ilkd.key.gui.ExampleChooser; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; -import de.uka.ilkd.key.util.KeYConstants; -import org.eclipse.lsp4j.jsonrpc.CompletableFutures; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -@JsonSegment -public class KeyApiImpl implements KeyApi { - @Override - @JsonRequest - public CompletableFuture> examples() { - return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); - } - - @Override - public CompletableFuture shutdown() { - return CompletableFuture.completedFuture(null); - } - - @Override - public void exit() { - - } - - @Override - public void setTrace(SetTraceParams params) { - - } - - @Override - public CompletableFuture getVersion() { - return CompletableFuture.completedFuture(KeYConstants.VERSION); - } - - @Override - public CompletableFuture> getAvailableMacros() { - return CompletableFuture.completedFuture( - KeYApi.getMacroApi().getMacros().stream().map(MacroDescription::from) - .toList() - ); - } - - @Override - public CompletableFuture>> getAvailableScriptCommands() { - return CompletableFuture.completedFuture( - KeYApi.getScriptCommandApi().getScriptCommands().stream().toList()); - } -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java deleted file mode 100644 index 7eadda846ba..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -import java.io.File; -import java.util.List; - -public record LoadParams(File keyFile, File javaFile, List classPath, File bootClassPath, List includes) { - -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java similarity index 64% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java index df0112c51f2..a4a16b66b02 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java @@ -1,5 +1,6 @@ package org.keyproject.key.api.remoteapi; +import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; @@ -8,13 +9,13 @@ import java.util.concurrent.CompletableFuture; @JsonSegment("meta") -public interface KeyMetaApi { - @JsonRequest +public interface MetaApi { + @JsonRequest("version") CompletableFuture getVersion(); - @JsonRequest - CompletableFuture> getAvailableMacros(); + @JsonRequest("available_macros") + CompletableFuture> getAvailableMacros(); - @JsonRequest + @JsonRequest("available_script_commands") CompletableFuture>> getAvailableScriptCommands(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java new file mode 100644 index 00000000000..16c9f390b89 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java @@ -0,0 +1,48 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.Node; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.Statistics; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.keyproject.key.api.data.MacroStatistic; +import org.keyproject.key.api.data.NodeDesc; +import org.keyproject.key.api.data.StreategyOptions; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public interface ProofApi { + @JsonRequest + CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options); + + @JsonRequest + CompletableFuture macro(Proof proof, String macroId, StreategyOptions options); + + @JsonRequest + CompletableFuture auto(Proof proof, StreategyOptions options); + + @JsonRequest + CompletableFuture dispose(Proof proof); + + @JsonRequest + CompletableFuture goals(Proof proof); + + @JsonRequest + CompletableFuture tree(Proof proof); + + @JsonRequest + CompletableFuture root(Proof proof); + + @JsonRequest + CompletableFuture> children(Proof proof, Node nodeId); + + @JsonRequest + CompletableFuture> pruneTo(Proof proof, Node nodeId); + + @JsonRequest + CompletableFuture statistics(Proof proof); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java deleted file mode 100644 index 7d1d4eb5d6b..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -public record ProofId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java deleted file mode 100644 index 49081037dc0..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -import de.uka.ilkd.key.proof.io.ProblemLoaderException; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - -@JsonSegment -public interface ProofLoading { - @JsonRequest - ProofId loadExample(String id); - - /** - * @param params - * @return - * @throws ProblemLoaderException - */ - @JsonRequest - EnvId load(LoadParams params) throws ProblemLoaderException; -} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java new file mode 100644 index 00000000000..88f5cad0330 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java @@ -0,0 +1,26 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.Proof; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.TreeNodeDesc; +import org.keyproject.key.api.data.TreeNodeId; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("proofTree") +public interface ProofTreeApi { + @JsonRequest("root") + CompletableFuture treeRoot(Proof id); + + @JsonRequest("children") + CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId); + + @JsonRequest("subtree") + CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java new file mode 100644 index 00000000000..ddd1fe408e6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java @@ -0,0 +1,60 @@ +package org.keyproject.key.api.remoteapi; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.TraceValue; + +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("server") +public interface ServerManagement { + /** + * Shutdown Request (:leftwards_arrow_with_hook:) + * The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. + *

+ * If a server receives requests after a shutdown request those requests should error with InvalidRequest. + *

+ * Request: + *

+ * method: ‘shutdown’ + * params: none + * Response: + *

+ * result: null + * error: code and message set in case an exception happens during shutdown request. + */ + @JsonRequest + CompletableFuture shutdown(); + + /** + * Exit Notification (:arrow_right:) + * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. + *

+ * Notification: + *

+ * method: ‘exit’ + * params: none + */ + @JsonNotification + void exit(); + + + interface SetTraceParams { + /** + * The new value that should be assigned to the trace setting. + */ + TraceValue value = null; + } + + /** + * SetTrace Notification + * A notification that should be used by the client to modify the trace setting of the server. + */ + @JsonNotification + void setTrace(SetTraceParams params); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java index 6f02b10a186..a7aebdca1bf 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -7,7 +7,7 @@ import javax.annotation.Nullable; import java.util.concurrent.CompletableFuture; -@JsonSegment +@JsonSegment("client") public interface ClientApi { @JsonNotification void sayHello(String e); diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java index 3370f6eb31f..1b63674ce67 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -18,7 +18,7 @@ public void logTrace(LogTraceParams params) { } @Override - public void userResponse(ShowMessageParams params) { + public void showMessage(ShowMessageParams params) { } diff --git a/keyext.api/src/test/java/org/keyproject/key/api/Client.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java similarity index 57% rename from keyext.api/src/test/java/org/keyproject/key/api/Client.java rename to keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index 4922de0993a..edbe4aee393 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/Client.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -2,6 +2,9 @@ import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; @@ -11,13 +14,17 @@ import java.io.PrintWriter; import java.util.Collections; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; -public class Client { - public static void main(String[] args) throws IOException, ExecutionException, InterruptedException, TimeoutException { +public class TestRpc { + private Future clientListening, serverListening; + private KeyApi keyApi; + + @BeforeEach + void setup() throws IOException, ExecutionException, InterruptedException, TimeoutException { PipedInputStream inClient = new PipedInputStream(); PipedOutputStream outClient = new PipedOutputStream(); PipedInputStream inServer = new PipedInputStream(); @@ -41,13 +48,33 @@ public static void main(String[] args) throws IOException, ExecutionException, I Logger logger = Logger.getLogger(StreamMessageProducer.class.getName()); logger.setLevel(Level.SEVERE); - var clientListening = clientLauncher.startListening(); - var serverListening = serverLauncher.startListening(); + clientListening = clientLauncher.startListening(); + serverListening = serverLauncher.startListening(); + + keyApi = clientLauncher.getRemoteProxy(); + } + + @AfterEach + void teardown() throws ExecutionException, InterruptedException, TimeoutException { + serverListening.cancel(true); + clientListening.cancel(true); + } + + + @Test + public void hello() { - //clientLauncher.getRemoteProxy().examples(); - serverLauncher.getRemoteProxy().sayHello("Alex"); + } + + @Test + public void listMacros() throws ExecutionException, InterruptedException { + var examples = keyApi.getAvailableMacros().get(); + System.out.println(examples); + } - serverListening.get(1, TimeUnit.SECONDS); - clientListening.get(1, TimeUnit.SECONDS); + @Test + public void listExamples() throws ExecutionException, InterruptedException { + var examples = keyApi.examples().get(); + System.out.println(examples); } } diff --git a/settings.gradle b/settings.gradle index a7fccaa51b6..f2d7206d797 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,3 +15,4 @@ include 'keyext.exploration' include 'keyext.slicing' include 'keyext.api' +include 'keyext.api.doc' From a049fa55e232917758409ea25d612a2f6c49f769 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 29 Oct 2023 16:45:43 +0100 Subject: [PATCH 05/50] working on a working minimal version --- .../src/main/java/org/key_project/Main.java | 3 +- .../AbstractSymbolicExecutionTestCase.java | 1636 +++++++++-------- .../java/de/uka/ilkd/key/Identifiable.java | 11 - .../key/control/AbstractProofControl.java | 13 +- .../ilkd/key/control/DefaultProofControl.java | 51 +- .../de/uka/ilkd/key/control/ProofControl.java | 10 +- .../key/macros/ProofMacroFinishedInfo.java | 1 + .../ilkd/key/macros/ProofMacroListener.java | 2 +- .../main/java/de/uka/ilkd/key/proof/Node.java | 79 +- .../java/de/uka/ilkd/key/proof/Proof.java | 12 +- .../ilkd/key/proof/io/TestZipProofSaving.java | 2 +- .../de/uka/ilkd/key/gui/ProofMacroWorker.java | 39 +- .../uka/ilkd/key/gui/ProofScriptWorker.java | 7 + .../key/gui/actions/RunAllProofsAction.java | 25 +- .../key/ui/ConsoleUserInterfaceControl.java | 8 +- .../uka/ilkd/key/ui/MediatorProofControl.java | 22 +- .../org/keyproject/key/api/KeyApiImpl.java | 487 ++++- .../org/keyproject/key/api/NodeTextDesc.java | 8 + .../org/keyproject/key/api/NodeTextId.java | 10 + .../org/keyproject/key/api/StartServer.java | 16 +- .../keyproject/key/api/TermActionUtil.java | 125 ++ .../key/api/adapters/KeyAdapter.java | 29 +- .../keyproject/key/api/data/ContractDesc.java | 11 +- .../keyproject/key/api/data/FunctionDesc.java | 13 +- .../org/keyproject/key/api/data/GoalText.java | 10 - .../key/api/data/KeyIdentifications.java | 163 ++ .../key/api/data/MacroStatistic.java | 9 +- .../org/keyproject/key/api/data/NodeDesc.java | 12 +- .../org/keyproject/key/api/data/PrintId.java | 8 - .../key/api/data/ProofMacroDesc.java | 14 + .../key/api/data/ProofScriptCommandDesc.java | 13 + .../org/keyproject/key/api/data/SortDesc.java | 13 +- .../keyproject/key/api/data/TermAction.java | 8 - .../key/api/data/TermActionDesc.java | 11 + .../keyproject/key/api/data/TermActionId.java | 6 - .../key/api/data/TermActionKind.java | 9 + .../keyproject/key/api/data/TreeNodeId.java | 6 - .../keyproject/key/api/internal/NodeText.java | 12 + .../keyproject/key/api/remoteapi/EnvApi.java | 13 +- .../keyproject/key/api/remoteapi/GoalApi.java | 17 +- .../keyproject/key/api/remoteapi/KeyApi.java | 2 +- .../keyproject/key/api/remoteapi/MetaApi.java | 9 +- .../key/api/remoteapi/PrintOptions.java | 9 + .../key/api/remoteapi/ProofApi.java | 23 +- .../ProofLoadApi.java} | 25 +- .../key/api/remoteapi/ProofTreeApi.java | 10 +- .../key/api/remoteclient/ClientApi.java | 7 + .../org/keyproject/key/api/SimpleClient.java | 17 + .../java/org/keyproject/key/api/TestRpc.java | 7 +- .../ProofExplorationServiceTest.java | 47 +- 50 files changed, 2000 insertions(+), 1100 deletions(-) delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/Identifiable.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java rename keyext.api/src/main/java/org/keyproject/key/api/{data/ProofLoading.java => remoteapi/ProofLoadApi.java} (50%) diff --git a/key.core.example/src/main/java/org/key_project/Main.java b/key.core.example/src/main/java/org/key_project/Main.java index 51ba6c5547d..4da18d230e9 100644 --- a/key.core.example/src/main/java/org/key_project/Main.java +++ b/key.core.example/src/main/java/org/key_project/Main.java @@ -92,6 +92,7 @@ private static void proveEnvironmemt(KeYEnvironment env) { for (Contract contract : proofContracts) { proveContract(env, contract); } + } catch (InterruptedException ignored) { } finally { env.dispose(); // Ensure always that all instances of KeYEnvironment are disposed } @@ -130,7 +131,7 @@ private static List getContracts(KeYEnvironment env) { * @param env the {@link KeYEnvironment} in which to prove the contract * @param contract the {@link Contract} to be proven */ - private static void proveContract(KeYEnvironment env, Contract contract) { + private static void proveContract(KeYEnvironment env, Contract contract) throws InterruptedException { Proof proof = null; try { // Create proof diff --git a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java index 95c6da8fe33..907a15d5c9d 100644 --- a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java +++ b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java @@ -44,7 +44,6 @@ import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionUtil; import de.uka.ilkd.key.util.HelperClassForTests; import de.uka.ilkd.key.util.KeYConstants; - import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableList; @@ -52,11 +51,15 @@ import org.key_project.util.helper.FindResources; import org.key_project.util.java.CollectionUtil; import org.key_project.util.java.StringUtil; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.IOException; +import java.util.*; + import static org.junit.jupiter.api.Assertions.*; /** @@ -66,7 +69,7 @@ */ public abstract class AbstractSymbolicExecutionTestCase { private static final Logger LOGGER = - LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); + LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); /** *

@@ -83,7 +86,7 @@ public abstract class AbstractSymbolicExecutionTestCase { *

*/ public static final boolean CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY = - Boolean.getBoolean("UPDATE_TEST_ORACLE"); + Boolean.getBoolean("UPDATE_TEST_ORACLE"); static { @@ -99,13 +102,13 @@ public abstract class AbstractSymbolicExecutionTestCase { * Number of executed SET nodes to execute all in one. */ public static final int ALL_IN_ONE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; /** * Number of executed SET nodes for only one SET node per auto mode run. */ public static final int SINGLE_SET_NODE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; /** * Default stop conditions of executed SET nodes. @@ -132,9 +135,9 @@ public abstract class AbstractSymbolicExecutionTestCase { static { // Define fast mode if (FAST_MODE) { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN }; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN}; } else { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN }; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN}; } // Create temporary director for oracle files if required. File directory = null; @@ -157,18 +160,18 @@ public abstract class AbstractSymbolicExecutionTestCase { /** * Creates a new oracle file. * - * @param node The node to save as oracle file. + * @param node The node to save as oracle file. * @param oraclePathInBaseDirFile The path in example directory. - * @param saveConstraints Save constraints? - * @param saveVariables Save variables? - * @param saveCallStack Save call stack? - * @param saveReturnValues Save method return values? - * @throws IOException Occurred Exception + * @param saveConstraints Save constraints? + * @param saveVariables Save variables? + * @param saveCallStack Save call stack? + * @param saveReturnValues Save method return values? + * @throws IOException Occurred Exception * @throws ProofInputException Occurred Exception */ protected static void createOracleFile(IExecutionNode node, String oraclePathInBaseDirFile, - boolean saveConstraints, boolean saveVariables, boolean saveCallStack, - boolean saveReturnValues) throws IOException, ProofInputException { + boolean saveConstraints, boolean saveVariables, boolean saveCallStack, + boolean saveReturnValues) throws IOException, ProofInputException { if (tempNewOracleDirectory != null && tempNewOracleDirectory.isDirectory()) { // Create sub folder structure File oracleFile = new File(tempNewOracleDirectory, oraclePathInBaseDirFile); @@ -176,7 +179,7 @@ protected static void createOracleFile(IExecutionNode node, String oraclePath // Create oracle file ExecutionNodeWriter writer = new ExecutionNodeWriter(); writer.write(node, ExecutionNodeWriter.DEFAULT_ENCODING, oracleFile, saveVariables, - saveCallStack, saveReturnValues, saveConstraints); + saveCallStack, saveReturnValues, saveConstraints); // Print message to the user. printOracleDirectory(); } @@ -204,37 +207,37 @@ protected static void printOracleDirectory() { /** * Makes sure that the given nodes and their subtrees contains the same content. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? - * @param compareChildOrder Is the order of children relevant? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? + * @param compareChildOrder Is the order of children relevant? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { if (compareChildOrder) { // Order of children must be the same. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { // Order of children is not relevant. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); Set> currentVisitedNodes = new LinkedHashSet<>(); while (expectedExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); @@ -243,11 +246,11 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo fail("Node " + currentNext + " visited twice."); } assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } // Make sure that each current node was visited ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); if (!currentVisitedNodes.remove(currentNext)) { @@ -261,13 +264,13 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo /** * Searches the direct or indirect child in subtree of the node to search in. * - * @param toSearchIn The node to search in. + * @param toSearchIn The node to search in. * @param childToSearch The node to search. * @return The found node. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearchIn, - IExecutionNode childToSearch) throws ProofInputException { + IExecutionNode childToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(toSearchIn); assertNotNull(childToSearch); @@ -288,20 +291,20 @@ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearc } } assertNotNull(toSearchIn, "Direct or indirect Child " + childToSearch - + " is not contained in " + toSearchIn + "."); + + " is not contained in " + toSearchIn + "."); return toSearchIn; } /** * Searches the direct child. Nodes are equal if the name and the element type is equal. * - * @param parentToSearchIn The parent to search in its children. + * @param parentToSearchIn The parent to search in its children. * @param directChildToSearch The child to search. * @return The found child. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchDirectChildNode(IExecutionNode parentToSearchIn, - IExecutionNode directChildToSearch) throws ProofInputException { + IExecutionNode directChildToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(parentToSearchIn); assertNotNull(directChildToSearch); @@ -315,60 +318,60 @@ protected static IExecutionNode searchDirectChildNode(IExecutionNode paren if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) directChildToSearch) - .getAdditionalBranchLabel()) + ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) directChildToSearch) + .getAdditionalBranchLabel()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } else { if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } i++; } assertNotNull(result, - "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); + "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); return result; } /** * Makes sure that the given nodes contains the same content. Children are not compared. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareParent Compare also the parent node? - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareParent Compare also the parent node? + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertExecutionNode(IExecutionNode expected, IExecutionNode current, - boolean compareParent, boolean compareVariables, boolean compareCallStack, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareParent, boolean compareVariables, boolean compareCallStack, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { // Compare nodes assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); + "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); assertEquals(expected.isPathConditionChanged(), current.isPathConditionChanged()); if (!StringUtil.equalIgnoreWhiteSpace(expected.getFormatedPathCondition(), - current.getFormatedPathCondition())) { + current.getFormatedPathCondition())) { assertEquals(expected.getFormatedPathCondition(), current.getFormatedPathCondition()); } if (compareParent) { if (expected instanceof IExecutionBlockStartNode) { assertTrue(current instanceof IExecutionBlockStartNode); assertEquals(((IExecutionBlockStartNode) expected).isBlockOpened(), - ((IExecutionBlockStartNode) current).isBlockOpened()); + ((IExecutionBlockStartNode) current).isBlockOpened()); assertBlockCompletions((IExecutionBlockStartNode) expected, - (IExecutionBlockStartNode) current); + (IExecutionBlockStartNode) current); } assertCompletedBlocks(expected, current); assertOutgoingLinks(expected, current); @@ -377,177 +380,177 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution if (expected instanceof IExecutionBaseMethodReturn) { assertTrue(current instanceof IExecutionBaseMethodReturn); assertCallStateVariables((IExecutionBaseMethodReturn) expected, - (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); + (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); } if (expected instanceof IExecutionBranchCondition) { assertTrue(current instanceof IExecutionBranchCondition, - "Expected IExecutionBranchCondition but is " + current.getClass() + "."); + "Expected IExecutionBranchCondition but is " + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), - ((IExecutionBranchCondition) current).getFormatedBranchCondition()), - "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), + ((IExecutionBranchCondition) current).getFormatedBranchCondition()), + "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); assertEquals(((IExecutionBranchCondition) expected).isMergedBranchCondition(), - ((IExecutionBranchCondition) current).isMergedBranchCondition()); + ((IExecutionBranchCondition) current).isMergedBranchCondition()); assertEquals(((IExecutionBranchCondition) expected).isBranchConditionComputed(), - ((IExecutionBranchCondition) current).isBranchConditionComputed()); + ((IExecutionBranchCondition) current).isBranchConditionComputed()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), - "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), + "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStart) { assertTrue(current instanceof IExecutionStart, "Expected IExecutionStartNode but is " - + current.getClass() + "."); + + current.getClass() + "."); assertTerminations((IExecutionStart) expected, (IExecutionStart) current); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionTermination) { assertTrue(current instanceof IExecutionTermination, - "Expected IExecutionTermination but is " - + current.getClass() + "."); + "Expected IExecutionTermination but is " + + current.getClass() + "."); assertEquals(((IExecutionTermination) expected).getTerminationKind(), - ((IExecutionTermination) current).getTerminationKind()); + ((IExecutionTermination) current).getTerminationKind()); assertEquals(((IExecutionTermination) expected).isBranchVerified(), - ((IExecutionTermination) current).isBranchVerified()); + ((IExecutionTermination) current).isBranchVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionBranchStatement) { assertTrue(current instanceof IExecutionBranchStatement, - "Expected IExecutionBranchStatement but is " - + current.getClass() + "."); + "Expected IExecutionBranchStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopCondition) { assertTrue(current instanceof IExecutionLoopCondition, - "Expected IExecutionLoopCondition but is " - + current.getClass() + "."); + "Expected IExecutionLoopCondition but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopStatement) { assertTrue(current instanceof IExecutionLoopStatement, - "Expected IExecutionLoopStatement but is " - + current.getClass() + "."); + "Expected IExecutionLoopStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionMethodCall) { assertTrue(current instanceof IExecutionMethodCall, - "Expected IExecutionMethodCall but is " - + current.getClass() + "."); + "Expected IExecutionMethodCall but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); assertMethodReturns((IExecutionMethodCall) expected, (IExecutionMethodCall) current); } else if (expected instanceof IExecutionMethodReturn) { assertTrue(current instanceof IExecutionMethodReturn, - "Expected IExecutionMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), - ((IExecutionMethodReturn) current).getSignature()), - ((IExecutionMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), + ((IExecutionMethodReturn) current).getSignature()), + ((IExecutionMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionMethodReturn) current).getSignature()); if (compareReturnValues) { assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), - ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), - ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); assertEquals(((IExecutionMethodReturn) expected).isReturnValuesComputed(), - ((IExecutionMethodReturn) current).isReturnValuesComputed()); + ((IExecutionMethodReturn) current).isReturnValuesComputed()); } assertTrue( - StringUtil.equalIgnoreWhiteSpace( + StringUtil.equalIgnoreWhiteSpace( ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + + " does not match " + ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); if (compareReturnValues) { assertReturnValues(((IExecutionMethodReturn) expected).getReturnValues(), - ((IExecutionMethodReturn) current).getReturnValues()); + ((IExecutionMethodReturn) current).getReturnValues()); } } else if (expected instanceof IExecutionExceptionalMethodReturn) { assertTrue(current instanceof IExecutionExceptionalMethodReturn, - "Expected IExecutionExceptionalMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionExceptionalMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionExceptionalMethodReturn) expected).getSignature(), - ((IExecutionExceptionalMethodReturn) current).getSignature()), - ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionExceptionalMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionExceptionalMethodReturn) expected).getSignature(), + ((IExecutionExceptionalMethodReturn) current).getSignature()), + ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionExceptionalMethodReturn) current).getSignature()); assertTrue(StringUtil.equalIgnoreWhiteSpace( ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionExceptionalMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + ((IExecutionExceptionalMethodReturn) current) + + " does not match " + ((IExecutionExceptionalMethodReturn) current) .getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStatement) { assertTrue(current instanceof IExecutionStatement, - "Expected IExecutionStatement but is " - + current.getClass() + "."); + "Expected IExecutionStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionOperationContract) { assertTrue(current instanceof IExecutionOperationContract, - "Expected IExecutionOperationContract but is " - + current.getClass() + "."); + "Expected IExecutionOperationContract but is " + + current.getClass() + "."); assertEquals(((IExecutionOperationContract) expected).isPreconditionComplied(), - ((IExecutionOperationContract) current).isPreconditionComplied()); + ((IExecutionOperationContract) current).isPreconditionComplied()); assertEquals(((IExecutionOperationContract) expected).hasNotNullCheck(), - ((IExecutionOperationContract) current).hasNotNullCheck()); + ((IExecutionOperationContract) current).hasNotNullCheck()); assertEquals(((IExecutionOperationContract) expected).isNotNullCheckComplied(), - ((IExecutionOperationContract) current).isNotNullCheckComplied()); + ((IExecutionOperationContract) current).isNotNullCheckComplied()); assertEquals(((IExecutionOperationContract) expected).getFormatedResultTerm(), - ((IExecutionOperationContract) current).getFormatedResultTerm()); + ((IExecutionOperationContract) current).getFormatedResultTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedExceptionTerm(), - ((IExecutionOperationContract) current).getFormatedExceptionTerm()); + ((IExecutionOperationContract) current).getFormatedExceptionTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedSelfTerm(), - ((IExecutionOperationContract) current).getFormatedSelfTerm()); + ((IExecutionOperationContract) current).getFormatedSelfTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedContractParams(), - ((IExecutionOperationContract) current).getFormatedContractParams()); + ((IExecutionOperationContract) current).getFormatedContractParams()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopInvariant) { assertTrue(current instanceof IExecutionLoopInvariant, - "Expected IExecutionLoopInvariant but is " - + current.getClass() + "."); + "Expected IExecutionLoopInvariant but is " + + current.getClass() + "."); assertEquals(((IExecutionLoopInvariant) expected).isInitiallyValid(), - ((IExecutionLoopInvariant) current).isInitiallyValid()); + ((IExecutionLoopInvariant) current).isInitiallyValid()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionAuxiliaryContract) { assertTrue(current instanceof IExecutionAuxiliaryContract, - "Expected IExecutionBlockContract but is " - + current.getClass() + "."); + "Expected IExecutionBlockContract but is " + + current.getClass() + "."); assertEquals(((IExecutionAuxiliaryContract) expected).isPreconditionComplied(), - ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); + ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionJoin) { assertTrue(current instanceof IExecutionJoin, "Expected IExecutionJoin but is " - + current.getClass() + "."); + + current.getClass() + "."); assertEquals(((IExecutionJoin) expected).isWeakeningVerified(), - ((IExecutionJoin) current).isWeakeningVerified()); + ((IExecutionJoin) current).isWeakeningVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else { @@ -559,22 +562,22 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution IExecutionNode[] currentStack = current.getCallStack(); if (expectedStack != null) { assertNotNull(currentStack, - "Call stack of \"" + current + "\" should not be null."); + "Call stack of \"" + current + "\" should not be null."); assertEquals(expectedStack.length, currentStack.length, "Node: " + expected); for (int i = 0; i < expectedStack.length; i++) { assertExecutionNode(expectedStack[i], currentStack[i], false, false, false, - false, false); + false, false); } } else { assertTrue(currentStack == null || currentStack.length == 0, - "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) - + "\" but should be null or empty."); + "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) + + "\" but should be null or empty."); } } // Optionally compare parent if (compareParent) { assertExecutionNode(expected, current, false, compareVariables, compareCallStack, - compareReturnValues, compareConstraints); + compareReturnValues, compareConstraints); } } @@ -582,7 +585,7 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution * Compares the outgoing links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertOutgoingLinks(IExecutionNode expected, IExecutionNode current) @@ -591,9 +594,9 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getOutgoingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Outgoing links of \"" + current + "\" should not be null."); + "Outgoing links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Outgoing links: " + expected); + "Outgoing links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -601,15 +604,15 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Outgoing links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -617,7 +620,7 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution * Compares the incoming links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertIncomingLinks(IExecutionNode expected, IExecutionNode current) @@ -626,9 +629,9 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getIncomingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Incoming links of \"" + current + "\" should not be null."); + "Incoming links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Incoming links: " + expected); + "Incoming links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -636,15 +639,15 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Incoming links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -652,29 +655,29 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution * Compares the completed blocks. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertCompletedBlocks(IExecutionNode expected, - IExecutionNode current) throws ProofInputException { + IExecutionNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getCompletedBlocks(); ImmutableList> currentEntries = current.getCompletedBlocks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Completed blocks of \"" + current + "\" should not be null."); + "Completed blocks of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionBlockStartNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionBlockStartNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, false, false, - false, false, false); + false, false, false); String expectedCondition = - expected.getFormatedBlockCompletionCondition(expectedNext); + expected.getFormatedBlockCompletionCondition(expectedNext); String currentCondition = current.getFormatedBlockCompletionCondition(currentNext); if (!StringUtil.equalIgnoreWhiteSpace(expectedCondition, currentCondition)) { assertEquals(expectedCondition, currentCondition); @@ -684,8 +687,8 @@ protected static void assertCompletedBlocks(IExecutionNode expected, assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Completed block entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Completed block entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -693,33 +696,33 @@ protected static void assertCompletedBlocks(IExecutionNode expected, * Compares the block completions. * * @param expected The expected {@link IExecutionBlockStartNode}. - * @param current The current {@link IExecutionBlockStartNode}. + * @param current The current {@link IExecutionBlockStartNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertBlockCompletions(IExecutionBlockStartNode expected, - IExecutionBlockStartNode current) throws ProofInputException { + IExecutionBlockStartNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getBlockCompletions(); ImmutableList> currentEntries = current.getBlockCompletions(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Block completions of \"" + current + "\" should not be null."); + "Block completions of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Block completion entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Block completion entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -727,34 +730,34 @@ protected static void assertBlockCompletions(IExecutionBlockStartNode expecte * Compares the method returns. * * @param expected The expected {@link IExecutionMethodCall}. - * @param current The current {@link IExecutionMethodCall}. + * @param current The current {@link IExecutionMethodCall}. * @throws ProofInputException Occurred Exception. */ protected static void assertMethodReturns(IExecutionMethodCall expected, - IExecutionMethodCall current) throws ProofInputException { + IExecutionMethodCall current) throws ProofInputException { ImmutableList> expectedEntries = expected.getMethodReturns(); ImmutableList> currentEntries = current.getMethodReturns(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Method return of \"" + current + "\" should not be null."); + "Method return of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Method return entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Method return entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -762,7 +765,7 @@ protected static void assertMethodReturns(IExecutionMethodCall expected, * Compares the terminations. * * @param expected The expected {@link IExecutionStart}. - * @param current The current {@link IExecutionStart}. + * @param current The current {@link IExecutionStart}. * @throws ProofInputException Occurred Exception. */ protected static void assertTerminations(IExecutionStart expected, IExecutionStart current) @@ -773,22 +776,22 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta assertNotNull(currentEntries, "Termination of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Termination entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Termination entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -796,11 +799,11 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta * Makes sure that the given nodes contains the same {@link IExecutionMethodReturnValue}s. * * @param expected The expected {@link IExecutionMethodReturnValue}s. - * @param current The current {@link IExecutionMethodReturnValue}s. + * @param current The current {@link IExecutionMethodReturnValue}s. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, - IExecutionMethodReturnValue[] current) throws ProofInputException { + IExecutionMethodReturnValue[] current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertEquals(expected.length, current.length); @@ -813,36 +816,36 @@ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, * Makes sure that the given {@link IExecutionMethodReturnValue}s are the same. * * @param expected The expected {@link IExecutionMethodReturnValue}. - * @param current The current {@link IExecutionMethodReturnValue}. + * @param current The current {@link IExecutionMethodReturnValue}. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValue(IExecutionMethodReturnValue expected, - IExecutionMethodReturnValue current) throws ProofInputException { + IExecutionMethodReturnValue current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), - current.getReturnValueString()), - expected.getReturnValueString() + " does not match " + current.getReturnValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), + current.getReturnValueString()), + expected.getReturnValueString() + " does not match " + current.getReturnValueString()); assertEquals(expected.hasCondition(), current.hasCondition()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); } /** * Makes sure that the given nodes contains the same {@link IExecutionNode}s. * - * @param expected The expected node. - * @param current The current node. + * @param expected The expected node. + * @param current The current node. * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionNode expected, IExecutionNode current, - boolean compareConstraints) throws ProofInputException { + boolean compareConstraints) throws ProofInputException { if (compareConstraints) { assertNotNull(expected); assertNotNull(current); @@ -856,26 +859,26 @@ protected static void assertConstraints(IExecutionNode expected, IExecutionNo * Makes sure that the given constraints are the same. * * @param expected The expected constraints. - * @param current The current constraints. + * @param current The current constraints. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionConstraint[] expected, - IExecutionConstraint[] current) throws ProofInputException { + IExecutionConstraint[] current) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionConstraint expectedVariable : expected) { // Find current variable with same name IExecutionConstraint currentVariable = CollectionUtil.searchAndRemove( - availableCurrentVariables, element -> { - try { - return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); - } catch (ProofInputException e) { - throw new RuntimeException(e); - } - }); + availableCurrentVariables, element -> { + try { + return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), + element.getName()); + } catch (ProofInputException e) { + throw new RuntimeException(e); + } + }); assertNotNull(currentVariable); // Compare variables assertConstraint(expectedVariable, currentVariable); @@ -887,11 +890,11 @@ protected static void assertConstraints(IExecutionConstraint[] expected, * Makes sure that the given constraints are the same. * * @param expected The expected constraint. - * @param current The current constraint. + * @param current The current constraint. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraint(IExecutionConstraint expected, - IExecutionConstraint current) throws ProofInputException { + IExecutionConstraint current) throws ProofInputException { if (expected != null) { assertNotNull(current); if (!StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName())) { @@ -906,15 +909,15 @@ protected static void assertConstraint(IExecutionConstraint expected, * Makes sure that the given nodes contains the same {@link IExecutionVariable}s of the call * state. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertCallStateVariables(IExecutionBaseMethodReturn expected, - IExecutionBaseMethodReturn current, boolean compareVariables, - boolean compareConstraints) throws ProofInputException { + IExecutionBaseMethodReturn current, boolean compareVariables, + boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -927,14 +930,14 @@ protected static void assertCallStateVariables(IExecutionBaseMethodReturn exp /** * Makes sure that the given nodes contains the same {@link IExecutionVariable}s. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -947,27 +950,27 @@ protected static void assertVariables(IExecutionNode expected, IExecutionNode /** * Makes sure that the given variables are the same. * - * @param expected The expected variables. - * @param current The current variables. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variables. + * @param current The current variables. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionVariable[] expected, - IExecutionVariable[] current, boolean compareParent, boolean compareChildren, - boolean compareConstraints) throws ProofInputException { + IExecutionVariable[] current, boolean compareParent, boolean compareChildren, + boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionVariable expectedVariable : expected) { // Find current variable with same name IExecutionVariable currentVariable = CollectionUtil .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); + element.getName()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -975,7 +978,7 @@ protected static void assertVariables(IExecutionVariable[] expected, assertNotNull(currentVariable); // Compare variables assertVariable(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -983,15 +986,15 @@ protected static void assertVariables(IExecutionVariable[] expected, /** * Makes sure that the given variables are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariable(IExecutionVariable expected, IExecutionVariable current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); @@ -1002,7 +1005,7 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari // Compare parent if (compareParent) { assertValue(expected.getParentValue(), current.getParentValue(), false, false, - false); + false); } // Compare children if (compareChildren) { @@ -1018,15 +1021,15 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari /** * Makes sure that the given values are the same. * - * @param expected The expected values. - * @param current The current values. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected values. + * @param current The current values. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order @@ -1037,10 +1040,10 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()) + element.getName()) && StringUtil.equalIgnoreWhiteSpace( - expectedVariable.getConditionString(), - element.getConditionString()); + expectedVariable.getConditionString(), + element.getConditionString()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -1048,7 +1051,7 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] assertNotNull(currentVariable); // Compare variables assertValue(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -1056,43 +1059,43 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] /** * Makes sure that the given values are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValue(IExecutionValue expected, IExecutionValue current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); // Compare variable assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertEquals(expected.getTypeString(), current.getTypeString()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), - current.getValueString()), - expected.getValueString() + " does not match " + current.getValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), + current.getValueString()), + expected.getValueString() + " does not match " + current.getValueString()); assertEquals(expected.isValueAnObject(), current.isValueAnObject()); assertEquals(expected.isValueUnknown(), current.isValueUnknown()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); // Compare parent if (compareParent) { assertVariable(expected.getVariable(), current.getVariable(), false, false, - compareConstraints); + compareConstraints); } // Compare children if (compareChildren) { IExecutionVariable[] expectedChildVariables = expected.getChildVariables(); IExecutionVariable[] currentChildVariables = current.getChildVariables(); assertVariables(expectedChildVariables, currentChildVariables, compareParent, - compareChildren, compareConstraints); + compareChildren, compareConstraints); } // Compare constraints if (compareConstraints) { @@ -1109,37 +1112,41 @@ protected static void assertValue(IExecutionValue expected, IExecutionValue curr * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturn(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + try { + ui.getProofControl().startAndWaitForAutoMode(proof); + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } @@ -1147,164 +1154,182 @@ protected static void stepReturn(DefaultUserInterfaceControl ui, * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); stopCondition.addChildren(lineBreakpoints); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); - // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + try { + // Run proof + ui.getProofControl().startAndWaitForAutoMode(proof); + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Executes a "step over" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepOver(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepOverSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); - // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + try { + // Run proof + ui.getProofControl().startAndWaitForAutoMode(proof); + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. * @return The found {@link SymbolicExecutionCompletions}. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - SymbolicExecutionCompletions completions = builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); - return completions; + try { + ui.getProofControl().startAndWaitForAutoMode(proof); + + // Update symbolic execution tree + SymbolicExecutionCompletions completions = builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + return completions; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void resume(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, baseDir); + try { + ui.getProofControl().startAndWaitForAutoMode(proof); + + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, File baseDir) + String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { if (CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { createOracleFile(builder.getStartNode(), oraclePathInBaseDirFile, false, false, false, - false); + false); } else { // Read oracle file File oracleFile = new File(baseDir, oraclePathInBaseDirFile); @@ -1313,41 +1338,41 @@ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builde assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, builder.getStartNode(), false, false, false, false, - false); + false); } } /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, - File baseDir) + String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, + File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { assertSetTreeAfterStep(builder, - oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); + oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); } /** * Searches a {@link IProgramMethod} in the given {@link Services}. * - * @param services The {@link Services} to search in. + * @param services The {@link Services} to search in. * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. + * @param methodFullName The method name to search. * @return The first found {@link IProgramMethod} in the type. */ public static IProgramMethod searchProgramMethod(Services services, String containerTypeName, - final String methodFullName) { + final String methodFullName) { return HelperClassForTests.searchProgramMethod(services, containerTypeName, methodFullName); } @@ -1356,29 +1381,29 @@ public static IProgramMethod searchProgramMethod(Services services, String conta * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param baseContractName The name of the contract. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param baseContractName The name of the contract. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String baseContractName, @@ -1392,26 +1417,26 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, - null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, + null, null, null, true); setupTacletOptions(environment); // Start proof final Contract contract = environment.getServices().getSpecificationRepository() .getContractByName(baseContractName); assertTrue(contract instanceof FunctionalOperationContract); ProofOblInput input = new FunctionalOperationContractPO(environment.getInitConfig(), - (FunctionalOperationContract) contract, true, true); + (FunctionalOperationContract) contract, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1423,30 +1448,30 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1460,25 +1485,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodPO(environment.getInitConfig(), pm.getFullName(), pm, - precondition, true, true); + precondition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1501,26 +1526,26 @@ private static void setupTacletOptions(KeYEnvironment env) { * Creates a {@link SymbolicExecutionEnvironment} which consists of loading a proof file to load * and creation with configuration of {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param proofPathInBaseDir The path to the proof file inside the base directory. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofPathInBaseDir The path to the proof file inside the base directory. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. */ @@ -1537,20 +1562,20 @@ protected static SymbolicExecutionEnvironment creat assertTrue(proofFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, - null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, + null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); setupTacletOptions(environment); Proof proof = environment.getLoadedProof(); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1562,32 +1587,32 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param startPosition The start position. - * @param endPosition The end position. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param startPosition The start position. + * @param endPosition The end position. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1602,25 +1627,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodSubsetPO(environment.getInitConfig(), methodFullName, - pm, precondition, startPosition, endPosition, true, true); + pm, precondition, startPosition, endPosition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1645,7 +1670,7 @@ protected String getTryContent(Proof proof) { JavaProgramElement updateContent = updateApplication.subs().get(1).javaBlock().program(); assertTrue(updateContent instanceof StatementBlock); ImmutableArray updateContentBody = - ((StatementBlock) updateContent).getBody(); + ((StatementBlock) updateContent).getBody(); assertEquals(2, updateContentBody.size()); assertTrue(updateContentBody.get(1) instanceof Try); Try tryStatement = (Try) updateContentBody.get(1); @@ -1656,39 +1681,39 @@ protected String getTryContent(Proof proof) { /** * Makes sure that the save and loading process works. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. * @param oraclePathInBaseDirFile The oracle path. - * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof - * to save/load. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof + * to save/load. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, - String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) + String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) throws IOException, ProofInputException, ParserConfigurationException, SAXException, ProblemLoaderException { File javaFile = new File(baseDir, javaPathInBaseDir); assertTrue(javaFile.exists()); File tempFile = - File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); + File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); KeYEnvironment reloadedEnv = null; SymbolicExecutionTreeBuilder reloadedBuilder = null; try { ProofSaver saver = new ProofSaver(env.getProof(), tempFile.getAbsolutePath(), - KeYConstants.INTERNAL_VERSION); + KeYConstants.INTERNAL_VERSION); assertNull(saver.save()); // Load proof from saved *.proof file reloadedEnv = KeYEnvironment.load(SymbolicExecutionJavaProfile.getDefaultInstance(), - tempFile, null, null, null, true); + tempFile, null, null, null, true); Proof reloadedProof = reloadedEnv.getLoadedProof(); assertNotSame(env.getProof(), reloadedProof); // Recreate symbolic execution tree reloadedBuilder = - new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); + new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); SymbolicExecutionUtil.initializeStrategy(reloadedBuilder); reloadedBuilder.analyse(); assertSetTreeAfterStep(reloadedBuilder, oraclePathInBaseDirFile, baseDir); @@ -1717,59 +1742,59 @@ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? * @param maximalNumberOfExecutedSetNodesPerRun The number of executed set nodes per auto mode - * run. The whole test is executed for each defined value. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. - * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * run. The whole test is executed for each defined value. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. + * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containerTypeName, - String methodFullName, String precondition, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String methodFullName, String precondition, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { assertNotNull(maximalNumberOfExecutedSetNodesPerRun); for (int j : maximalNumberOfExecutedSetNodesPerRun) { SymbolicExecutionEnvironment env = doSETTest(baseDir, - javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, j, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, j, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } } @@ -1778,57 +1803,57 @@ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containe * Executes method doTest * and disposes the created {@link SymbolicExecutionEnvironment}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, - String containerTypeName, String methodFullName, String precondition, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String containerTypeName, String methodFullName, String precondition, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, simplifyConditions); + doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } @@ -1845,47 +1870,47 @@ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, - includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, false, true); + doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, + includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, false, true); if (env != null) { env.dispose(); } @@ -1904,47 +1929,47 @@ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String proofFilePathInBaseDir, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String proofFilePathInBaseDir, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { boolean originalOneStepSimplification = isOneStepSimplificationEnabled(null); SymbolicExecutionEnvironment env; @@ -1955,26 +1980,26 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } // Make sure that the correct taclet options are defined. setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution env = createSymbolicExecutionEnvironment(baseDir, proofFilePathInBaseDir, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, - simplifyConditions); + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, + simplifyConditions); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); return env; } finally { // Restore original options @@ -1995,49 +2020,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String containerTypeName, final String methodFullName, - String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, - boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String javaPathInBaseDir, String containerTypeName, final String methodFullName, + String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, + boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; @@ -2051,23 +2076,23 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = setDefaultTacletOptions(baseDir, javaPathInBaseDir, - containerTypeName, methodFullName); + containerTypeName, methodFullName); setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, precondition, mergeBranchConditions, useOperationContracts, - useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, - aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, precondition, mergeBranchConditions, useOperationContracts, + useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, + aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore original options @@ -2089,49 +2114,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param baseContractName The name of the contract. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseContractName The name of the contract. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; try { @@ -2142,22 +2167,22 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = - setDefaultTacletOptions(javaPathInBaseDir, baseContractName); + setDefaultTacletOptions(javaPathInBaseDir, baseContractName); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, - useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - truthValueEvaluationEnabled, simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, + useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + truthValueEvaluationEnabled, simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore taclet options @@ -2169,67 +2194,72 @@ protected SymbolicExecutionEnvironment doSETTest(Fi * Internal test method */ private void internalDoSETTest(File oracleFile, - SymbolicExecutionEnvironment env, - String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues) + SymbolicExecutionEnvironment env, + String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); + new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); env.getProof().getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); int nodeCount; // Execute auto mode until no more symbolic execution tree nodes are found or no new rules // are applied. do { - // Store the number of nodes before start of the auto mode - nodeCount = env.getProof().countNodes(); - // Run proof - env.getProofControl().startAndWaitForAutoMode(env.getProof()); - // Update symbolic execution tree - env.getBuilder().analyse(); - // Make sure that not to many set nodes are executed - Map executedSetNodesPerGoal = stopCondition.getExectuedSetNodesPerGoal(); - for (Integer value : executedSetNodesPerGoal.values()) { - assertNotNull(value); - assertTrue(value <= maximalNumberOfExecutedSetNodes, - value + " is not less equal to " + maximalNumberOfExecutedSetNodes); + try { + // Store the number of nodes before start of the auto mode + nodeCount = env.getProof().countNodes(); + // Run proof + env.getProofControl().startAndWaitForAutoMode(env.getProof()); + + // Update symbolic execution tree + env.getBuilder().analyse(); + // Make sure that not to many set nodes are executed + Map executedSetNodesPerGoal = stopCondition.getExectuedSetNodesPerGoal(); + for (Integer value : executedSetNodesPerGoal.values()) { + assertNotNull(value); + assertTrue(value <= maximalNumberOfExecutedSetNodes, + value + " is not less equal to " + maximalNumberOfExecutedSetNodes); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); } } while (stopCondition.wasSetNodeExecuted() && nodeCount != env.getProof().countNodes()); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); } /** * Ensures that the default taclet options are defined. * * @param javaPathInBaseDir The path in the base directory to the java file. - * @param baseContractName The name of the contract to prove. + * @param baseContractName The name of the contract to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(String javaPathInBaseDir, - String baseContractName) + String baseContractName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, - baseContractName, - false, false, false, - false, false, false, - false, false, false, - false, false); + createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, + baseContractName, + false, false, false, + false, false, false, + false, false, false, + false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2238,26 +2268,26 @@ public static Map setDefaultTacletOptions(String javaPathInBaseD /** * Ensures that the default taclet options are defined. * - * @param baseDir The base directory which contains the java file. + * @param baseDir The base directory which contains the java file. * @param javaPathInBaseDir The path in the base directory to the java file. * @param containerTypeName name of the type where the method is implemented/declared - * @param methodFullName The method to prove. + * @param methodFullName The method to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(File baseDir, - String javaPathInBaseDir, - String containerTypeName, - String methodFullName) + String javaPathInBaseDir, + String containerTypeName, + String methodFullName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, - null, false, false, false, - false, false, false, false, - false, false, false); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, + null, false, false, false, + false, false, false, false, + false, false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2266,19 +2296,19 @@ public static Map setDefaultTacletOptions(File baseDir, /** * Ensures that the default taclet options are defined. * - * @param javaFile The java file to load. + * @param javaFile The java file to load. * @param containerTypeName The type name which provides the target. - * @param targetName The target to proof. + * @param targetName The target to proof. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ @SuppressWarnings("unused") public static Map setDefaultTacletOptionsForTarget(File javaFile, - String containerTypeName, final String targetName) + String containerTypeName, final String targetName) throws ProblemLoaderException, ProofInputException { return HelperClassForTests.setDefaultTacletOptionsForTarget(javaFile, containerTypeName, - targetName); + targetName); } /** @@ -2312,14 +2342,14 @@ public static void restoreTacletOptions(Map options) { protected ITermProgramVariableCollectorFactory createNewProgramVariableCollectorFactory( final SymbolicExecutionBreakpointStopCondition breakpointParentStopCondition) { return services -> new TermProgramVariableCollectorKeepUpdatesForBreakpointconditions( - services, breakpointParentStopCondition); + services, breakpointParentStopCondition); } /** * Makes sure that two {@link Term}s are equal. * * @param expected The expected {@link Term}. - * @param actual The actual {@link Term}. + * @param actual The actual {@link Term}. */ protected void assertTerm(Term expected, Term actual) { if (expected != null) { @@ -2339,7 +2369,7 @@ protected void assertTerm(Term expected, Term actual) { * Checks if one-step simplification is enabled in the given {@link Proof}. * * @param proof The {@link Proof} to read from or {@code null} to return the general settings - * value. + * value. * @return {@code true} one step simplification is enabled, {@code false} if disabled. */ public static boolean isOneStepSimplificationEnabled(Proof proof) { @@ -2349,9 +2379,9 @@ public static boolean isOneStepSimplificationEnabled(Proof proof) { /** * Defines if one-step simplification is enabled in general and within the {@link Proof}. * - * @param proof The optional {@link Proof}. + * @param proof The optional {@link Proof}. * @param enabled {@code true} use one-step simplification, {@code false} do not use one-step - * simplification. + * simplification. */ public static void setOneStepSimplificationEnabled(Proof proof, boolean enabled) { HelperClassForTests.setOneStepSimplificationEnabled(proof, enabled); diff --git a/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java b/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java deleted file mode 100644 index 3be1d2528d8..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.uka.ilkd.key; - -/** - * @author Alexander Weigl - * @version 1 (14.10.23) - */ -public interface Identifiable { - default String identification() { - return getClass().getName() + "_" + hashCode(); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java index 0d3fd45622c..29a34424d09 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java @@ -550,19 +550,12 @@ protected void fireAutoModeStopped(ProofEvent e) { } } - /** - * {@inheritDoc} - */ - @Override - public void startAutoMode(Proof proof) { - startAutoMode(proof, proof.openEnabledGoals()); - } /** * {@inheritDoc} */ @Override - public void startAndWaitForAutoMode(Proof proof) { + public void startAndWaitForAutoMode(Proof proof) throws InterruptedException { startAutoMode(proof); waitWhileAutoMode(); } @@ -571,7 +564,7 @@ public void startAndWaitForAutoMode(Proof proof) { * {@inheritDoc} */ @Override - public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) { + public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException { startAutoMode(proof, goals); waitWhileAutoMode(); } @@ -580,7 +573,7 @@ public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) { * {@inheritDoc} */ @Override - public void stopAndWaitAutoMode() { + public void stopAndWaitAutoMode() throws InterruptedException { stopAutoMode(); waitWhileAutoMode(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java index df59e0c1ae7..48dda5aa1f3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java @@ -16,9 +16,11 @@ import de.uka.ilkd.key.prover.impl.ApplyStrategy; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; import de.uka.ilkd.key.util.ProofStarter; - import org.key_project.util.collection.ImmutableList; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + /** * The default implementation of {@link ProofControl}. * @@ -35,15 +37,20 @@ public class DefaultProofControl extends AbstractProofControl { */ private Thread autoModeThread; + /** + * A condition which is non-null during auto-mode. You can wait for end of macro/auto on it. + */ + private Condition inAutoMode; + /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. + * to all started {@link ApplyStrategy} instances. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener) { + DefaultUserInterfaceControl defaultProverTaskListener) { super(defaultProverTaskListener); this.ui = ui; } @@ -51,21 +58,21 @@ public DefaultProofControl(UserInterfaceControl ui, /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * to all started {@link ApplyStrategy} instances. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener, - RuleCompletionHandler ruleCompletionHandler) { + DefaultUserInterfaceControl defaultProverTaskListener, + RuleCompletionHandler ruleCompletionHandler) { super(defaultProverTaskListener, ruleCompletionHandler); this.ui = ui; } @Override public synchronized void startAutoMode(Proof proof, ImmutableList goals, - ProverTaskListener ptl) { + ProverTaskListener ptl) { if (!isInAutoMode()) { autoModeThread = new AutoModeThread(proof, goals, ptl); autoModeThread.start(); @@ -79,19 +86,17 @@ public synchronized void stopAutoMode() { } } + @Override - public void waitWhileAutoMode() { - while (isInAutoMode()) { // Wait until auto mode has stopped. - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } + public void waitWhileAutoMode() throws InterruptedException { + if (inAutoMode != null) { + inAutoMode.await(); } } @Override public boolean isInAutoMode() { - return autoModeThread != null; + return inAutoMode != null; } private class AutoModeThread extends Thread { @@ -105,6 +110,9 @@ public AutoModeThread(Proof proof, ImmutableList goals, ProverTaskListener this.proof = proof; this.goals = goals; this.ptl = ptl; + + var lock = new ReentrantLock(); + inAutoMode = lock.newCondition(); } @Override @@ -113,7 +121,7 @@ public void run() { fireAutoModeStarted(new ProofEvent(proof)); ProofStarter starter = ptl != null ? new ProofStarter( - new CompositePTListener(getDefaultProverTaskListener(), ptl), false) + new CompositePTListener(getDefaultProverTaskListener(), ptl), false) : new ProofStarter(getDefaultProverTaskListener(), false); starter.init(proof); if (goals != null) { @@ -122,6 +130,8 @@ public void run() { starter.start(); } } finally { + inAutoMode.signalAll(); + inAutoMode = null; autoModeThread = null; fireAutoModeStopped(new ProofEvent(proof)); } @@ -150,6 +160,9 @@ public MacroThread(Node node, ProofMacro macro, PosInOccurrence posInOcc) { this.node = node; this.macro = macro; this.posInOcc = posInOcc; + + var lock = new ReentrantLock(); + inAutoMode = lock.newCondition(); } @Override @@ -172,7 +185,9 @@ public void run() { if (ptl != null) { ptl.taskFinished(info); } + inAutoMode.signalAll(); autoModeThread = null; + inAutoMode = null; fireAutoModeStopped(new ProofEvent(proof)); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java index 77b71eaf5df..f30b7bb97d1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java @@ -123,7 +123,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * * @param proof The {@link Proof} to start auto mode of. */ - void startAutoMode(Proof proof); + default void startAutoMode(Proof proof) { startAutoMode(proof, proof.openEnabledGoals());} /** * Starts the auto mode for the given {@link Proof} and the given {@link Goal}s. @@ -143,13 +143,13 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * Stops the currently running auto mode and blocks the current {@link Thread} until auto mode * has stopped. */ - void stopAndWaitAutoMode(); + void stopAndWaitAutoMode() throws InterruptedException; /** * Blocks the current {@link Thread} while the auto mode of this {@link UserInterfaceControl} is * active. */ - void waitWhileAutoMode(); + void waitWhileAutoMode() throws InterruptedException; /** * Starts the auto mode for the given proof which must be contained in this user interface and @@ -158,7 +158,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * @param proof The {@link Proof} to start auto mode and to wait for. * @param goals The {@link Goal}s to close. */ - void startAndWaitForAutoMode(Proof proof, ImmutableList goals); + void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException; /** * Starts the auto mode for the given proof which must be contained in this user interface and @@ -166,7 +166,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * * @param proof The {@link Proof} to start auto mode and to wait for. */ - void startAndWaitForAutoMode(Proof proof); + void startAndWaitForAutoMode(Proof proof) throws InterruptedException; void startFocussedAutoMode(PosInOccurrence focus, Goal goal); diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java index 962228f3ca8..ebe8d366f00 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.macros; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java index 2844075269b..d024e192f97 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java @@ -35,7 +35,7 @@ public void taskStarted(TaskStartedInfo info) { numOfInvokedMacros++; if (superordinateListener != null) { superordinateListener.taskStarted(new DefaultTaskStartedInfo(TaskKind.Macro, - macroName + (macroName.length() == 0 ? "" : " -- ") + info.message(), + macroName + (macroName.isEmpty() ? "" : " -- ") + info.message(), info.size())); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 533828bb803..06da529607f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -23,13 +23,15 @@ import de.uka.ilkd.key.rule.RuleApp; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.util.Pair; - import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.collection.ImmutableSet; import org.key_project.util.lookup.Lookup; +import java.util.*; +import java.util.stream.Stream; + import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -49,10 +51,14 @@ public class Node implements Iterable { private static final String NODES = "nodes"; - /** the proof the node belongs to */ + /** + * the proof the node belongs to + */ private final Proof proof; - /** The parent node. **/ + /** + * The parent node. + **/ private Node parent = null; /** * The branch location of this proof node. @@ -81,7 +87,9 @@ public class Node implements Iterable { private boolean closed = false; - /** contains non-logical content, used for user feedback */ + /** + * contains non-logical content, used for user feedback + */ private NodeInfo nodeInfo; /** @@ -119,7 +127,7 @@ public class Node implements Iterable { * taclet with an addrule section on this node, then these taclets are stored in this list */ private ImmutableSet localIntroducedRules = - DefaultImmutableSet.nil(); + DefaultImmutableSet.nil(); /** * Holds the undo methods for the information added by rules to the {@code Goal.strategyInfos}. @@ -162,7 +170,9 @@ public void setSequent(Sequent seq) { this.seq = seq; } - /** returns the sequent of this node */ + /** + * returns the sequent of this node + */ public Sequent sequent() { return seq; } @@ -176,7 +186,9 @@ public NodeInfo getNodeInfo() { return nodeInfo; } - /** returns the proof the Node belongs to */ + /** + * returns the proof the Node belongs to + */ public Proof proof() { return proof; } @@ -225,14 +237,16 @@ public RuleApp getAppliedRuleApp() { return appliedRuleApp; } - /** Returns the set of NoPosTacletApps at this node */ + /** + * Returns the set of NoPosTacletApps at this node + */ public Iterable getLocalIntroducedRules() { return localIntroducedRules; } /** * Returns the set of created program variables known in this node. - * + *

    * In the resulting list, the newest additions come first. * * @returns a non-null immutable list of program variables. @@ -249,7 +263,7 @@ public void addLocalProgVars(Iterable elements) { /** * Returns the set of freshly created function symbols known to this node. - * + *

    * In the resulting list, the newest additions come first. * * @return a non-null immutable list of function symbols. @@ -444,7 +458,7 @@ List getLeaves() { /** * @return an iterator for the leaves of the subtree below this node. The computation is called - * at every call! + * at every call! */ public Iterator leavesIterator() { return new NodeIterator(getLeaves().iterator()); @@ -471,13 +485,14 @@ public Iterator subtreeIterator() { return new SubtreeIterator(this); } - /** @return number of children */ + /** + * @return number of children + */ public int childrenCount() { return children.size(); } /** - * * @param i an index (starting at 0). * @return the i-th child of this node. */ @@ -488,7 +503,7 @@ public Node child(int i) { /** * @param child a child of this node. * @return the number of the node child, if it is a child of this node (starting - * with 0), -1 otherwise + * with 0), -1 otherwise */ public int getChildNr(Node child) { int res = 0; @@ -528,16 +543,16 @@ public StringBuffer getUniqueTacletId() { * Helper for {@link #toString()} * * @param prefix needed to keep track if a line has to be printed - * @param tree the tree representation we want to add this subtree " @param preEnumeration the - * enumeration of the parent without the last number + * @param tree the tree representation we want to add this subtree " @param preEnumeration the + * enumeration of the parent without the last number * @param postNr the last number of the parents enumeration - * @param maxNr the number of nodes at this level - * @param ownNr the place of this node at this level + * @param maxNr the number of nodes at this level + * @param ownNr the place of this node at this level * @return the string representation of this node. */ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumeration, - int postNr, int maxNr, int ownNr) { + int postNr, int maxNr, int ownNr) { Iterator childrenIt = childrenIterator(); // Some constants String frontIndent = (maxNr > 1 ? " " : ""); @@ -588,7 +603,7 @@ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumer while (childrenIt.hasNext()) { childId++; childrenIt.next().toString(prefix, tree, newEnumeration, newPostNr, children.size(), - childId); + childId); } return tree; @@ -645,7 +660,7 @@ public String name() { * this node. * * @return true iff the parent of this node has this node as child and this condition holds also - * for the own children. + * for the own children. */ public boolean sanityCheckDoubleLinks() { if (!root()) { @@ -667,7 +682,9 @@ public boolean sanityCheckDoubleLinks() { return true; } - /** marks a node as closed */ + /** + * marks a node as closed + */ Node close() { closed = true; Node tmp = parent; @@ -684,7 +701,7 @@ Node close() { /** * Opens a previously closed node and all its closed parents. *

    - * + *

    * This is, for instance, needed for the {@link MergeRule}: In a situation where a merge node * and its associated partners have been closed and the merge node is then pruned away, the * partners have to be reopened again. Otherwise, we have a soundness issue. @@ -699,7 +716,9 @@ void reopen() { clearNameCache(); } - /** @return true iff this inner node is closeable */ + /** + * @return true iff this inner node is closeable + */ private boolean isCloseable() { assert childrenCount() > 0; for (Node child : children) { @@ -768,7 +787,7 @@ public Iterator iterator() { * Retrieves a user-defined data. * * @param service the class for which the data were registered - * @param any class + * @param any class * @return null or the previous data * @see #register(Object, Class) */ @@ -786,7 +805,7 @@ public T lookup(Class service) { /** * Register a user-defined data in this node info. * - * @param obj an object to be registered + * @param obj an object to be registered * @param service the key under it should be registered * @param */ @@ -797,9 +816,9 @@ public void register(T obj, Class service) { /** * Remove a previous registered user-defined data. * - * @param obj registered object + * @param obj registered object * @param service the key under which the data was registered - * @param arbitray object + * @param arbitray object */ public void deregister(T obj, Class service) { if (userData != null) { @@ -837,4 +856,8 @@ public int getStepIndex() { void setStepIndex(int stepIndex) { this.stepIndex = stepIndex; } + + public Stream childrenStream() { + return children.stream(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java index d7ac6c484d0..6b97d88d82d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java @@ -11,7 +11,6 @@ import java.util.function.Predicate; import javax.swing.*; -import de.uka.ilkd.key.Identifiable; import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.*; @@ -28,7 +27,6 @@ import de.uka.ilkd.key.proof.replay.CopyingProofReplayer; import de.uka.ilkd.key.rule.NoPosTacletApp; import de.uka.ilkd.key.rule.OneStepSimplifier; -import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.merge.MergePartner; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.rule.merge.MergeRuleBuiltInRuleApp; @@ -56,7 +54,7 @@ * information, and methods to apply rules. Furthermore, it offers services that deliver the open * goals, namespaces and several other information about the current state of the proof. */ -public class Proof implements Named, Identifiable { +public class Proof implements Named { /** * The time when the {@link Proof} instance was created. @@ -1477,12 +1475,4 @@ public void copyCachedGoals(Proof referencedFrom, Consumer callbackTota } } } - - /** - * {@inheritDoc} - */ - @Override - public String identification() { - return getClass().getName() + "_" + name + "_" + hashCode(); - } } diff --git a/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java b/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java index 57ad2025a7e..abd24dd8d6e 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java +++ b/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java @@ -33,7 +33,7 @@ private void loadZip(Path fileTarget) throws Exception { } private void proveAndSaveZip(Path file, Path fileTarget) - throws ProblemLoaderException, IOException { + throws ProblemLoaderException, InterruptedException { KeYEnvironment env = KeYEnvironment.load(file.toFile()); env.getProofControl().startAndWaitForAutoMode(env.getLoadedProof()); GZipProofSaver proofSaver = diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java index 6f634c192f1..a80815bbe03 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java @@ -3,10 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; -import java.util.ArrayList; -import java.util.List; -import javax.swing.*; - import de.uka.ilkd.key.control.InteractionListener; import de.uka.ilkd.key.core.InterruptListener; import de.uka.ilkd.key.core.KeYMediator; @@ -20,10 +16,15 @@ import de.uka.ilkd.key.prover.ProverTaskListener; import de.uka.ilkd.key.prover.TaskStartedInfo; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + /** * The Class ProofMacroWorker is a swing worker for the application of proof macros. *

    @@ -39,7 +40,7 @@ public class ProofMacroWorker extends SwingWorker * goals under the current pio, selection remains where it was. */ private static final boolean SELECT_GOAL_AFTER_MACRO = - Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); + Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); /** * The {@link Node} to start macro at. @@ -69,22 +70,26 @@ public class ProofMacroWorker extends SwingWorker private Exception exception; private final List interactionListeners = new ArrayList<>(); + private final Condition finish; + /** * Instantiates a new proof macro worker. * - * @param node the {@link Node} to start macro at. - * @param macro the macro, not null + * @param node the {@link Node} to start macro at. + * @param macro the macro, not null * @param mediator the mediator, not null * @param posInOcc the position, possibly null */ public ProofMacroWorker(Node node, ProofMacro macro, KeYMediator mediator, - PosInOccurrence posInOcc) { + PosInOccurrence posInOcc) { assert macro != null; assert mediator != null; this.node = node; this.macro = macro; this.mediator = mediator; this.posInOcc = posInOcc; + + finish = new ReentrantLock().newCondition(); } @Override @@ -93,7 +98,7 @@ protected ProofMacroFinishedInfo doInBackground() { Proof selectedProof = node.proof(); info = ProofMacroFinishedInfo.getDefaultInfo(macro, selectedProof); ptl.taskStarted( - new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); + new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); try { synchronized (macro) { info = macro.applyTo(mediator.getUI(), node, posInOcc, ptl); @@ -105,6 +110,8 @@ protected ProofMacroFinishedInfo doInBackground() { } catch (final Exception exception) { // This should actually never happen. this.exception = exception; + } finally { + finish.signalAll(); } return info; @@ -120,8 +127,7 @@ protected void done() { synchronized (macro) { mediator.removeInterruptedListener(this); if (!isCancelled() && exception != null) { // user cancelled task is fine, we do not - // report this - // This should actually never happen. + // report this // This should actually never happen. LOGGER.error("", exception); IssueDialog.showExceptionDialog(MainWindow.getInstance(), exception); } @@ -138,7 +144,7 @@ protected void done() { } protected void emitProofMacroFinished(Node node, ProofMacro macro, PosInOccurrence posInOcc, - ProofMacroFinishedInfo info) { + ProofMacroFinishedInfo info) { interactionListeners.forEach((l) -> l.runMacro(node, macro, posInOcc, info)); } @@ -167,4 +173,11 @@ private void selectOpenGoalBelow() { } } } + + /** + * @return a condition for waiting on this thread to be finished + */ + public Condition getFinish() { + return finish; + } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java index 6c94d762e00..90c9398b076 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java @@ -183,6 +183,13 @@ public void done() { } mediator.removeInterruptedListener(this); + runWithDeadline(() -> mediator.startInterface(true), 1000); + runWithDeadline(() -> { + try { + mediator.getUI().getProofControl().stopAndWaitAutoMode(); + } catch (InterruptedException ignored) { + } + }, 1000); final Proof proof = initiallySelectedGoal != null ? initiallySelectedGoal.proof() : mediator.getSelectedProof(); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java index ceaba6d1bb1..2b8a53215d5 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java @@ -24,6 +24,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.awt.event.ActionEvent; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + /** * This class provides an action for KeY UI which runs a set of specified proof files automatically. * The intent of this class is to have a massive test feature for the quality assurance of the KeY @@ -73,7 +83,7 @@ public class RunAllProofsAction extends MainWindowAction { @NonNull private List loadFiles() throws IOException { LOGGER.info("Use 'export {}=<...>' to set the input file for {}.", ENV_VARIABLE, - getClass().getSimpleName()); + getClass().getSimpleName()); InputStream stream; if (RUN_ALL_PROOFS_UI == null) { @@ -87,7 +97,7 @@ private List loadFiles() throws IOException { } try (BufferedReader in = - new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { return in.lines().filter(it -> !it.startsWith("#") && !it.trim().isEmpty()) .map(it -> (it.startsWith("/") ? new File(it) : new File(exampleDir, it)) .getAbsoluteFile()) @@ -110,13 +120,13 @@ public RunAllProofsAction(MainWindow mainWindow) { setName("Run all proofs"); setTooltip( - "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); + "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); } @Override public void actionPerformed(ActionEvent e) { - WindowUserInterfaceControl ui = mainWindow.getUserInterface(); + WindowUserInterfaceControl ui = mainWindow.getUserInterface(); for (int i = 0; i < files.size(); i++) { LOGGER.info("{}: {}\n", i, files.get(i)); } @@ -126,7 +136,7 @@ public void actionPerformed(ActionEvent e) { ui.reportStatus(this, "Run: " + absFile); LOGGER.info("Run: {}", absFile); ProblemLoader problemLoader = - ui.getProblemLoader(absFile, null, null, null, getMediator()); + ui.getProblemLoader(absFile, null, null, null, getMediator()); problemLoader.runSynchronously(); LOGGER.info("Loaded: {}", absFile); @@ -135,7 +145,10 @@ public void actionPerformed(ActionEvent e) { MediatorProofControl control = ui.getProofControl(); if (control.isAutoModeSupported(proof)) { control.startAutoMode(proof, proof.openEnabledGoals()); - control.waitWhileAutoMode(); + try { + control.waitWhileAutoMode(); + } catch (InterruptedException ignored) { + } } LOGGER.info("Finish: ({}) {}", getMediator().getSelectedProof().closed(), absFile); getMediator().getSelectedProof().dispose(); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java b/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java index 89c4cb0d06b..50c05be74fa 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java @@ -172,7 +172,11 @@ public void taskFinished(TaskFinishedInfo info) { } else if (macroChosen()) { applyMacro(); } else { - finish(proof); + try { + finish(proof); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } @@ -228,7 +232,7 @@ public void registerProofAggregate(ProofAggregate pa) { proofStack = proofStack.prepend(pa.getFirstProof()); } - void finish(Proof proof) { + void finish(Proof proof) throws InterruptedException { // setInteractive(false) has to be called because the ruleAppIndex // has to be notified that we work in auto mode (CS) mediator.setInteractive(false); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java b/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java index 54009075944..839de98f341 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import javax.swing.*; @@ -45,6 +47,8 @@ public class MediatorProofControl extends AbstractProofControl { private final AbstractMediatorUserInterfaceControl ui; private AutoModeWorker worker; + private Condition inAutoMode; + public MediatorProofControl(AbstractMediatorUserInterfaceControl ui) { super(ui, ui); this.ui = ui; @@ -101,17 +105,14 @@ public void stopAutoMode() { * {@inheritDoc} */ @Override - public void waitWhileAutoMode() { + public void waitWhileAutoMode() throws InterruptedException { if (SwingUtilities.isEventDispatchThread()) { LOGGER.error("", new IllegalStateException( "tried to block the UI thread whilst waiting for auto mode to finish")); return; // do not block the UI thread } - while (ui.getMediator().isInAutoMode()) { // Wait until auto mode has stopped. - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } + if (inAutoMode != null) { + inAutoMode.await(); } } @@ -138,6 +139,7 @@ public boolean isAutoModeSupported(Proof proof) { public void runMacro(Node node, ProofMacro macro, PosInOccurrence posInOcc) { KeYMediator mediator = ui.getMediator(); final ProofMacroWorker worker = new ProofMacroWorker(node, macro, mediator, posInOcc); + inAutoMode = worker.getFinish(); interactionListeners.forEach(worker::addInteractionListener); mediator.initiateAutoMode(node.proof(), true, false); mediator.addInterruptedListener(worker); @@ -174,6 +176,9 @@ public AutoModeWorker(final Proof proof, final ImmutableList goals, if (ui.getMediator().getAutoSaver() != null) { applyStrategy.addProverTaskObserver(ui.getMediator().getAutoSaver()); } + + var lock = new ReentrantLock(); + inAutoMode = lock.newCondition(); } @Override @@ -185,6 +190,9 @@ protected void done() { } catch (final CancellationException exception) { // when the user canceled it's not an error } finally { + // release threads waiting on automode finish + inAutoMode.signalAll(); + // make it possible to free memory and falsify the isAutoMode() property worker = null; // Clear strategy @@ -212,7 +220,7 @@ private void notifyException(final Throwable exception) { } @Override - protected ApplyStrategyInfo doInBackground() throws Exception { + protected ApplyStrategyInfo doInBackground() { boolean stopMode = proof.getSettings().getStrategySettings().getActiveStrategyProperties() .getProperty(StrategyProperties.STOPMODE_OPTIONS_KEY) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index 248210a9f7f..fd1b8352356 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -1,27 +1,75 @@ package org.keyproject.key.api; +import de.uka.ilkd.key.control.AbstractUserInterfaceControl; +import de.uka.ilkd.key.control.DefaultUserInterfaceControl; import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.gui.Example; import de.uka.ilkd.key.gui.ExampleChooser; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.ProofMacroFacade; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; import de.uka.ilkd.key.macros.scripts.ProofScriptCommandFacade; -import de.uka.ilkd.key.proof.Node; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.Statistics; +import de.uka.ilkd.key.macros.scripts.ProofScriptEngine; +import de.uka.ilkd.key.macros.scripts.ScriptException; +import de.uka.ilkd.key.parser.Location; +import de.uka.ilkd.key.pp.IdentitySequentPrintFilter; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.pp.NotationInfo; +import de.uka.ilkd.key.pp.PosTableLayouter; +import de.uka.ilkd.key.proof.*; +import de.uka.ilkd.key.proof.init.*; +import de.uka.ilkd.key.proof.io.AbstractProblemLoader; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import de.uka.ilkd.key.prover.ProverTaskListener; +import de.uka.ilkd.key.prover.TaskFinishedInfo; +import de.uka.ilkd.key.prover.TaskStartedInfo; +import de.uka.ilkd.key.speclang.PositionedString; import de.uka.ilkd.key.util.KeYConstants; import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.keyproject.key.api.adapters.KeyAdapter; +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSet; import org.keyproject.key.api.data.*; +import org.keyproject.key.api.data.KeyIdentifications.*; +import org.keyproject.key.api.internal.NodeText; import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteapi.PrintOptions; +import org.keyproject.key.api.remoteclient.ClientApi; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.concurrent.CompletableFuture; - -public record KeyApiImpl(KeyAdapter adapter) implements KeyApi { +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + +public final class KeyApiImpl implements KeyApi { + private final KeyIdentifications data = new KeyIdentifications(); + + private ClientApi clientApi; + private final ProverTaskListener clientListener = new ProverTaskListener() { + @Override + public void taskStarted(TaskStartedInfo info) { + clientApi.taskStarted(info); + } + + @Override + public void taskProgress(int position) { + clientApi.taskProgress(position); + } + + @Override + public void taskFinished(TaskFinishedInfo info) { + clientApi.taskFinished(info); + } + }; + private final AtomicInteger uniqueCounter = new AtomicInteger(); + + public KeyApiImpl() { + } @Override @JsonRequest @@ -49,120 +97,461 @@ public CompletableFuture getVersion() { } @Override - public CompletableFuture> getAvailableMacros() { + public CompletableFuture> getAvailableMacros() { return CompletableFuture.completedFuture( - ProofMacroFacade.instance().getMacros().stream().toList() + ProofMacroFacade.instance().getMacros().stream() + .map(ProofMacroDesc::from).toList() ); } @Override - public CompletableFuture>> getAvailableScriptCommands() { + public CompletableFuture> getAvailableScriptCommands() { return CompletableFuture.completedFuture( - ProofScriptCommandFacade.instance().getScriptCommands().stream().toList()); + ProofScriptCommandFacade.instance().getScriptCommands().stream().map(ProofScriptCommandDesc::from).toList()); } @Override - public CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options) { - return null; + public CompletableFuture script(ProofId proofId, String scriptLine, StreategyOptions options) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + var env = data.find(proofId.env()); + var pe = new ProofScriptEngine(scriptLine, Location.UNDEFINED); + + try { + pe.execute((AbstractUserInterfaceControl) env.getProofControl(), proof); + return null; + } catch (IOException | InterruptedException | ScriptException e) { + throw new RuntimeException(e); + } + }); } @Override - public CompletableFuture macro(Proof id, String macroId, StreategyOptions options) { - return null; + public CompletableFuture macro(ProofId proofId, String macroId, StreategyOptions options) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + var env = data.find(proofId.env()); + var macro = Objects.requireNonNull(ProofMacroFacade.instance().getMacro(macroId)); + + try { + var info = macro.applyTo(env.getUi(), proof, proof.openGoals(), null, clientListener); + return MacroStatistic.from(proofId, info); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } @Override - public CompletableFuture auto(Proof id, StreategyOptions options) { - return null; + public CompletableFuture auto(ProofId proofId, StreategyOptions options) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + var env = data.find(proofId.env()); + try { + env.getProofControl().startAndWaitForAutoMode(proof); + //clientListener); + return null;//MacroStatistic.from(proofId, info); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } @Override - public CompletableFuture dispose(Proof id) { - return null; + public CompletableFuture dispose(ProofId id) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(id); + data.dispose(id); + proof.dispose(); + return true; + }); } @Override - public CompletableFuture goals(Proof id) { - return null; + public CompletableFuture> goals(ProofId proofId, boolean onlyOpened, boolean onlyEnabled) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + if (onlyOpened && !onlyEnabled) { + return asNodeDesc(proofId, proof.openGoals()); + } else if (onlyEnabled && onlyOpened) { + return asNodeDesc(proofId, proof.openEnabledGoals()); + } else { + return asNodeDesc(proofId, proof.allGoals()); + } + }); + } + + private List asNodeDesc(ProofId proofId, ImmutableList goals) { + return asNodeDesc(proofId, goals.stream().map(Goal::node)); + } + + private List asNodeDesc(ProofId proofId, Stream nodes) { + return nodes.map(it -> asNodeDesc(proofId, it)).toList(); + } + + private NodeDesc asNodeDesc(ProofId proofId, Node it) { + return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), it.getNodeInfo().getScriptRuleApplication()); } @Override - public CompletableFuture tree(Proof proof) { - return null; + public CompletableFuture tree(ProofId proofId) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + return asNodeDescRecursive(proofId, proof.root()); + }); + } + + private NodeDesc asNodeDescRecursive(ProofId proofId, Node root) { + return new NodeDesc(new NodeId(proofId, root.serialNr()), + root.getNodeInfo().getBranchLabel(), + root.getNodeInfo().getScriptRuleApplication(), + root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList() + ); } @Override - public CompletableFuture root(Proof proof) { - return null; + public CompletableFuture root(ProofId proofId) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + return asNodeDesc(proofId, proof.root()); + }); } @Override - public CompletableFuture> children(Proof proof, Node nodeId) { - return null; + public CompletableFuture> children(NodeId nodeId) { + return CompletableFuture.supplyAsync(() -> { + var node = data.find(nodeId); + return asNodeDesc(nodeId.proofId(), node.childrenStream()); + }); } @Override - public CompletableFuture> pruneTo(Proof proof, Node nodeId) { + public CompletableFuture> pruneTo(NodeId nodeId) { return null; } @Override - public CompletableFuture statistics(Proof proof) { - return null; + public CompletableFuture statistics(ProofId proofId) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + return proof.getStatistics(); + }); } @Override - public CompletableFuture treeRoot(Proof proof) { + public CompletableFuture treeRoot(ProofId proof) { return null; } @Override - public CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId) { + public CompletableFuture> treeChildren(ProofId proof, TreeNodeId nodeId) { return null; } @Override - public CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId) { + public CompletableFuture> treeSubtree(ProofId proof, TreeNodeId nodeId) { return null; } @Override - public CompletableFuture> sorts(KeYEnvironment env) { - return null; + public CompletableFuture> sorts(EnvironmentId envId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(envId); + var sorts = env.getServices().getNamespaces().sorts().allElements(); + return sorts.stream().map(SortDesc::from).toList(); + }); } @Override - public CompletableFuture> functions(KeYEnvironment env) { - return null; + public CompletableFuture> functions(EnvironmentId envId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(envId); + var functions = env.getServices().getNamespaces().functions().allElements(); + return functions.stream().map(FunctionDesc::from).toList(); + }); } @Override - public CompletableFuture> contracts(KeYEnvironment env) { - return null; + public CompletableFuture> contracts(EnvironmentId envId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(envId); + var contracts = env.getAvailableContracts(); + return contracts.stream().map(it -> ContractDesc.from(envId, env.getServices(), it)).toList(); + }); } @Override - public CompletableFuture openContract(KeYEnvironment env, String contractId) { - return null; + public CompletableFuture openContract(ContractId contractId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(contractId.envId()); + var contracts = env.getAvailableContracts(); + var contract = contracts.stream().filter(it -> it.id() == contractId.contractId()).findFirst(); + if (contract.isPresent()) { + try { + var proof = env.createProof(contract.get().createProofObl(env.getInitConfig())); + return data.register(contractId.envId(), proof); + } catch (ProofInputException e) { + throw new RuntimeException(e); + } + } else { + return null; + } + }); } @Override - public CompletableFuture print(Node id) { - return null; + public CompletableFuture print(NodeId nodeId, PrintOptions options) { + return CompletableFuture.supplyAsync(() -> { + var node = data.find(nodeId); + var env = data.find(nodeId.proofId().env()); + var notInfo = new NotationInfo(); + final var layouter = new PosTableLayouter(options.width(), options.indentation(), options.pure()); + var lp = new LogicPrinter(notInfo, env.getServices(), layouter); + lp.printSequent(node.sequent()); + + var id = new NodeTextId(nodeId, uniqueCounter.getAndIncrement()); + var t = new NodeText(lp.result(), layouter.getInitialPositionTable()); + data.register(id, t); + return new NodeTextDesc(id, lp.result()); + }); } + private final IdentitySequentPrintFilter filter = new IdentitySequentPrintFilter(); + @Override - public CompletableFuture> actions(PrintId id, int pos) { - return null; + public CompletableFuture> actions(NodeTextId printId, int pos) { + return CompletableFuture.supplyAsync(() -> { + var node = data.find(printId.nodeId()); + var proof = data.find(printId.nodeId().proofId()); + var goal = proof.getOpenGoal(node); + var nodeText = data.find(printId); + var pis = nodeText.table().getPosInSequent(pos, filter); + return new TermActionUtil(printId, data.find(printId.nodeId().proofId().env()), pis, goal) + .getActions(); + }); + } @Override - public CompletableFuture> applyAction(TermActionId id) { + public CompletableFuture> applyAction(TermActionId id) { return null; } @Override - public void freePrint(PrintId id) { + public void freePrint(NodeTextId printId) { + CompletableFuture.runAsync(() -> data.dispose(printId)); + } + + public void setClientApi(ClientApi remoteProxy) { + clientApi = remoteProxy; + } + + private final DefaultUserInterfaceControl control = new MyDefaultUserInterfaceControl(); + + @Override + public CompletableFuture loadExample(String id) { + return CompletableFutures.computeAsync((c) -> { + var examples = ExampleChooser.listExamples(ExampleChooser.lookForExamples()) + .stream().filter(it -> it.getName().equals(id)).findFirst(); + if (examples.isPresent()) { + var ex = examples.get(); + Proof proof = null; + KeYEnvironment env = null; + try { + var loader = control.load(JavaProfile.getDefaultProfile(), + ex.getObligationFile(), null, null, null, null, true, null); + InitConfig initConfig = loader.getInitConfig(); + + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + proof = Objects.requireNonNull(env.getLoadedProof()); + var proofId = new ProofId(envId, proof.name().toString()); + return data.register(proofId, proof); + } catch (ProblemLoaderException e) { + if (proof != null) proof.dispose(); + if (env != null) env.dispose(); + throw new RuntimeException(e); + } + } + throw new IllegalArgumentException("Unknown example"); + }); + } + + @Override + public CompletableFuture loadProblem(ProblemDefinition problem) { + return CompletableFutures.computeAsync((c) -> { + Proof proof = null; + KeYEnvironment env = null; + /* var loader = control.load(JavaProfile.getDefaultProfile(), + ex.getObligationFile(), null, null, null, null, true, null); + InitConfig initConfig = loader.getInitConfig(); + + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + proof = Objects.requireNonNull(env.getLoadedProof()); + var proofId = new ProofId(envId, proof.name().toString()); + return data.register(proofId, proof);*/ + return null; + }); } + + @Override + public CompletableFuture loadKey(String content) { + return CompletableFutures.computeAsync((c) -> { + Proof proof = null; + KeYEnvironment env = null; + try { + final var tempFile = File.createTempFile("json-rpc-", ".key"); + Files.writeString(tempFile.toPath(), content); + var loader = control.load(JavaProfile.getDefaultProfile(), + tempFile, null, null, null, null, true, null); + InitConfig initConfig = loader.getInitConfig(); + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + proof = Objects.requireNonNull(env.getLoadedProof()); + var proofId = new ProofId(envId, proof.name().toString()); + return data.register(proofId, proof); + } catch (ProblemLoaderException | IOException e) { + if (proof != null) proof.dispose(); + if (env != null) env.dispose(); + throw new RuntimeException(e); + } + }); + } + + @Override + public CompletableFuture loadTerm(String term) { + return loadKey("\\problem{ " + term + " }"); + } + + @Override + public CompletableFuture> load(LoadParams params) { + return CompletableFutures.computeAsync((c) -> { + Proof proof = null; + KeYEnvironment env = null; + try { + var loader = control.load(JavaProfile.getDefaultProfile(), + params.keyFile(), + params.classPath(), + params.bootClassPath(), + params.includes(), + null, + true, + null); + InitConfig initConfig = loader.getInitConfig(); + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + if ((proof = env.getLoadedProof()) != null) { + var proofId = new ProofId(envId, proof.name().toString()); + return Either.forRight(data.register(proofId, proof)); + } else { + return Either.forLeft(envId); + } + } catch (ProblemLoaderException e) { + if (proof != null) proof.dispose(); + if (env != null) env.dispose(); + throw new RuntimeException(e); + } + }); + } + + private class MyDefaultUserInterfaceControl extends DefaultUserInterfaceControl { + @Override + public void taskStarted(TaskStartedInfo info) { + clientApi.taskStarted(info); + } + + @Override + public void taskProgress(int position) { + clientApi.taskProgress(position); + } + + @Override + public void taskFinished(TaskFinishedInfo info) { + clientApi.taskFinished(info); + } + + @Override + protected void macroStarted(TaskStartedInfo info) { + clientApi.taskStarted(info); + } + + @Override + protected synchronized void macroFinished(ProofMacroFinishedInfo info) { + clientApi.taskFinished(info); + } + + @Override + public void loadingStarted(AbstractProblemLoader loader) { + super.loadingStarted(loader); + } + + @Override + public void loadingFinished(AbstractProblemLoader loader, IPersistablePO.LoadedPOContainer poContainer, ProofAggregate proofList, AbstractProblemLoader.ReplayResult result) throws ProblemLoaderException { + super.loadingFinished(loader, poContainer, proofList, result); + } + + @Override + public void progressStarted(Object sender) { + super.progressStarted(sender); + } + + @Override + public void progressStopped(Object sender) { + super.progressStopped(sender); + } + + @Override + public void reportStatus(Object sender, String status, int progress) { + super.reportStatus(sender, status, progress); + } + + @Override + public void reportStatus(Object sender, String status) { + super.reportStatus(sender, status); + } + + @Override + public void resetStatus(Object sender) { + super.resetStatus(sender); + } + + @Override + public void reportException(Object sender, ProofOblInput input, Exception e) { + super.reportException(sender, input, e); + } + + @Override + public void setProgress(int progress) { + super.setProgress(progress); + } + + @Override + public void setMaximum(int maximum) { + super.setMaximum(maximum); + } + + @Override + public void reportWarnings(ImmutableSet warnings) { + super.reportWarnings(warnings); + } + + @Override + public void showIssueDialog(Collection issues) { + super.showIssueDialog(issues); + } + } + + } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java new file mode 100644 index 00000000000..0a27c633e5a --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record NodeTextDesc(NodeTextId id, String result) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java new file mode 100644 index 00000000000..a99bed5fda9 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api; + +import org.keyproject.key.api.data.KeyIdentifications.NodeId; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record NodeTextId(NodeId nodeId, int nodeTextId) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index 408cc36acdd..b95ae6eebe2 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -115,6 +115,8 @@ public void run() { } try { + final var keyApi = new KeyApiImpl(); + if (websocket) { var launcherBuilder = new WebSocketLauncherBuilder() .setOutput(out) @@ -122,14 +124,18 @@ public void run() { .traceMessages(new PrintWriter(System.err)) .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - launcherBuilder.setLocalService(new KeyApiImpl(adapter)); + launcherBuilder.setLocalService(keyApi); launcherBuilder.setRemoteInterface(ClientApi.class); - launcherBuilder.create().startListening().get(); + + final var clientApiLauncher = launcherBuilder.create(); + keyApi.setClientApi(clientApiLauncher.getRemoteProxy()); + clientApiLauncher.startListening().get(); } else { establishStreams(); try (var lin = in; var lout = out) { - var listener = launch(lout, lin); + var listener = launch(lout, lin, keyApi); LOGGER.info("JSON-RPC is listening for requests"); + keyApi.setClientApi(listener.getRemoteProxy()); listener.startListening().get(); } } @@ -143,7 +149,7 @@ public static void configureJson(GsonBuilder gsonBuilder) { adapter = new KeyAdapter(gsonBuilder); } - public static Launcher launch(OutputStream out, InputStream in) { + public static Launcher launch(OutputStream out, InputStream in, KeyApiImpl keyApi) { // var localServices = getLocalServices(); // var remoteInterfaces = getRemoteInterfaces(); var launcherBuilder = new Launcher.Builder() @@ -154,7 +160,7 @@ public static Launcher launch(OutputStream out, InputStream in) { launcherBuilder.configureGson(StartServer::configureJson); //if (localServices != null && !localServices.isEmpty()) - launcherBuilder.setLocalService(new KeyApiImpl(adapter)); + launcherBuilder.setLocalService(keyApi); //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) launcherBuilder.setRemoteInterface(ClientApi.class); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java new file mode 100644 index 00000000000..51e0053eed6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -0,0 +1,125 @@ +package org.keyproject.key.api; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.control.ProofControl; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.PosInOccurrence; +import de.uka.ilkd.key.macros.ProofMacro; +import de.uka.ilkd.key.macros.ProofMacroFacade; +import de.uka.ilkd.key.pp.PosInSequent; +import de.uka.ilkd.key.proof.Goal; +import de.uka.ilkd.key.rule.*; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSLList; +import org.keyproject.key.api.data.KeyIdentifications; +import org.keyproject.key.api.data.TermActionDesc; +import org.keyproject.key.api.data.TermActionKind; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class TermActionUtil { + private static final Set CLUTTER_RULESETS = + Set.of(new Name("notHumanReadable"), + new Name("obsolete"), + new Name("pullOutQuantifierAll"), + new Name("pullOutQuantifierEx")); + private static final Set CLUTTER_RULES = Set.of( + new Name("cut_direct_r"), + new Name("cut_direct_l"), + new Name("case_distinction_r"), + new Name("case_distinction_l"), + new Name("local_cut"), + new Name("commute_and_2"), + new Name("commute_or_2"), + new Name("boxToDiamond"), + new Name("pullOut"), + new Name("typeStatic"), + new Name("less_is_total"), + new Name("less_zero_is_total"), + new Name("applyEqReverse"), + + // the following are used for drag'n'drop interactions + new Name("eqTermCut"), + new Name("instAll"), + new Name("instEx") + ); + private static final Set FILTER_SCRIPT_COMMANDS = Set.of( + "exit", + "leave", + "javascript", + "skip", + "macro", + "rule", + "script"); + + private final PosInSequent pos; + private final Goal goal; + private final PosInOccurrence occ; + + private final List actions = new ArrayList<>(1024); + private final NodeTextId nodeTextId; + + public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment env, @NonNull PosInSequent pos, @NonNull Goal goal) { + this.pos = pos; + this.goal = goal; + this.nodeTextId = nodeTextId; + occ = pos.getPosInOccurrence(); + ProofControl c = env.getUi().getProofControl(); + final ImmutableList builtInRules = c.getBuiltInRule(goal, occ); + for (ProofMacro macro : ProofMacroFacade.instance().getMacros()) { + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "macro:" + macro.getScriptCommandName()); + TermActionDesc ta = new TermActionDesc(id, macro.getName(), macro.getDescription(), macro.getCategory(), TermActionKind.Macro); + add(ta); + } + ImmutableList findTaclet = c.getFindTaclet(goal, occ); + var find = removeRewrites(findTaclet) + .prepend(c.getRewriteTaclet(goal, occ)); + var nofind = c.getNoFindTaclet(goal); + + + for (TacletApp tacletApp : find) { + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "find:" + tacletApp.rule()); + TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), + tacletApp.rule().toString(), "", TermActionKind.Taclet); + add(ta); + } + + for (TacletApp tacletApp : nofind) { + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "nofind:" + tacletApp.rule()); + TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), + tacletApp.rule().toString(), "", TermActionKind.Taclet); + add(ta); + } + } + + private void add(TermActionDesc ta) { + actions.add(ta); + } + + /** + * Removes RewriteTaclet from the list. + * + * @param list the IList from where the RewriteTaclet are removed + * @return list without RewriteTaclets + */ + private static ImmutableList removeRewrites( + ImmutableList list) { + ImmutableList result = ImmutableSLList.nil(); + for (TacletApp tacletApp : list) { + Taclet taclet = tacletApp.taclet(); + result = (taclet instanceof RewriteTaclet ? result : result.prepend(tacletApp)); + } + return result; + } + + public List getActions() { + return actions; + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 9168a2128f5..68b330491fc 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -1,20 +1,14 @@ package org.keyproject.key.api.adapters; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import de.uka.ilkd.key.Identifiable; import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.macros.ProofMacro; -import de.uka.ilkd.key.macros.ProofMacroFacade; -import de.uka.ilkd.key.proof.Proof; import org.keyproject.key.api.data.MacroDescription; import java.io.File; import java.io.IOException; -import java.lang.ref.WeakReference; import java.lang.reflect.Type; /** @@ -22,40 +16,39 @@ * @version 1 (14.10.23) */ public class KeyAdapter { - private final BiMap> map = HashBiMap.create(1024); + //private final BiMap> map = HashBiMap.create(1024); //private final TypeAdapter adaptor; public KeyAdapter(GsonBuilder gson) { gson.registerTypeAdapter(File.class, new FileTypeAdapter()); - gson.registerTypeAdapter(Function.class, new FunctionTypeAdapter()); - gson.registerTypeAdapter(Proof.class, new IdentifiableTypeAdapter()); - gson.registerTypeAdapter(ProofMacro.class, new MacroTypeAdapter()); - //adaptor = gson.create().getAdapter(Object.class); + //gson.registerTypeAdapter(Function.class, new FunctionSerializer()); + //gson.registerTypeAdapter(ProofMacro.class, new MacroSerializer()); } + /* //translating entities to identification strings - public String insert(Identifiable p) { + public void insert(Identifiable p) { var id = p.identification(); if (!map.containsKey(id)) { map.put(id, new WeakReference<>(p)); } - return id; } public Object find(String id) { return map.get(id).get(); } //endregion + */ - class MacroTypeAdapter implements JsonSerializer { + static class MacroSerializer implements JsonSerializer { @Override public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationContext context) { return context.serialize(MacroDescription.from(src)); } } - class FileTypeAdapter extends TypeAdapter { + static class FileTypeAdapter extends TypeAdapter { @Override public void write(JsonWriter out, File value) throws IOException { out.value(value.toString()); @@ -67,7 +60,7 @@ public File read(JsonReader in) throws IOException { } } - class FunctionTypeAdapter implements JsonSerializer { + static class FunctionSerializer implements JsonSerializer { @Override public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationContext context) { var obj = new JsonObject(); @@ -81,7 +74,7 @@ public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationCont } } - class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { + /*class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { @Override public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return (Identifiable) find(json.getAsString()); @@ -92,5 +85,5 @@ public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerialization insert(src); return context.serialize(src.identification()); } - } + }*/ } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java index a81f8d863db..531bc2fb56d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java @@ -1,8 +1,17 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.speclang.Contract; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record ContractDesc() { +public record ContractDesc(KeyIdentifications.ContractId contractId, String name, String displayName, + String typeName, String htmlText, String plainText) { + public static ContractDesc from(KeyIdentifications.EnvironmentId envId, Services services, Contract it) { + return new ContractDesc(new KeyIdentifications.ContractId(envId, it.id()), + it.getName(), it.getDisplayName(), it.getTypeName(), + it.getHTMLText(services), it.getPlainText(services)); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java index 0c612b44cc2..1868871c0e3 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -1,10 +1,21 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.logic.op.Function; + import java.util.List; /** * @author Alexander Weigl * @version 1 (15.10.23) */ -public record FunctionDesc(String name, String sort, List sorts) { +public record FunctionDesc(String name, String sort, SortDesc retSort, List argSorts, boolean rigid, + boolean unique, boolean skolemConstant) { + public static FunctionDesc from(Function fn) { + return new FunctionDesc(fn.name().toString(), fn.proofToString(), + SortDesc.from(fn.sort()), + fn.argSorts().stream().map(SortDesc::from).toList(), + fn.isRigid(), + fn.isUnique(), + fn.isSkolemConstant()); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java b/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java deleted file mode 100644 index 7a0e2f264e0..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.keyproject.key.api.data; - -import de.uka.ilkd.key.pp.PositionTable; - -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record GoalText(PrintId id, String text, PositionTable table) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java new file mode 100644 index 00000000000..0698a50a982 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java @@ -0,0 +1,163 @@ +package org.keyproject.key.api.data; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.proof.Node; +import de.uka.ilkd.key.proof.Proof; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.keyproject.key.api.NodeTextId; +import org.keyproject.key.api.internal.NodeText; + +import java.lang.ref.WeakReference; +import java.util.Objects; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class KeyIdentifications { + private final BiMap mapEnv = HashBiMap.create(16); + + public KeyEnvironmentContainer getContainer(EnvironmentId environmentId) { + return Objects.requireNonNull(mapEnv.get(environmentId), "Could not find environment for id" + environmentId); + } + + public ProofContainer getContainer(ProofId proofId) { + return Objects.requireNonNull(getContainer(proofId.env()).mapProof.get(proofId), + "Could not find proof for id" + proofId); + } + + public KeYEnvironment find(EnvironmentId envid) { + return Objects.requireNonNull(getContainer(envid).env.get(), "Environment was removed by gc"); + } + + @NonNull + public Proof find(ProofId proofId) { + return Objects.requireNonNull(getContainer(proofId).wProof.get(), "Could not find a proof for id " + proofId); + } + + @NonNull + public NodeText find(NodeTextId nodeTextId) { + return Objects.requireNonNull(getContainer(nodeTextId.nodeId().proofId()).mapGoalText.get(nodeTextId), + "Could not find a print-out with the id " + nodeTextId); + } + + public void dispose(NodeTextId nodeTextId) { + var c = getContainer(nodeTextId.nodeId().proofId()); + c.mapGoalText.remove(nodeTextId); + } + + public void dispose(ProofId id) { + var c = getContainer(id); + getContainer(id.env).mapProof.remove(id); + c.dispose(); + } + + public Node find(NodeId nodeId) { + @NonNull Proof p = find(nodeId.proofId); + var opt = p.findAny(it -> it.serialNr() == nodeId.nodeId()); + return Objects.requireNonNull(opt, "Could not find node with serialNr " + nodeId.nodeId); + } + + public ProofId register(EnvironmentId envId, Proof proof) { + var id = new ProofId(envId, proof.name().toString()); + getContainer(envId).mapProof.put(id, new ProofContainer(proof)); + return id; + } + + public void register(NodeTextId nodeId, NodeText nodeText) { + var c = getContainer(nodeId.nodeId().proofId()); + c.mapGoalText().put(nodeId, nodeText); + + } + + public EnvironmentId register(EnvironmentId envId, KeYEnvironment env) { + mapEnv.put(envId, new KeyEnvironmentContainer(env)); + return envId; + } + + public ProofId register(ProofId proofId, Proof proof) { + getContainer(proofId.env()).mapProof.put(proofId, new ProofContainer(proof)); + return proofId; + } + + + /** + * @author Alexander Weigl + * @version 1 (28.10.23) + */ + public record EnvironmentId(String envId) { + } + + /** + * @author Alexander Weigl + * @version 1 (28.10.23) + */ + public record ContractId(EnvironmentId envId, int contractId) { + } + + /** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ + public record NodeId(ProofId proofId, int nodeId) { + } + + public record ProofId(EnvironmentId env, String proofId) { + } + + /** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ + public record PrintId(String id) { + } + + /** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ + public record TermActionId(NodeId nodeId, String pio, String id) { + } + + /** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ + public record TreeNodeId(String id) { + } + + + /** + * @author Alexander Weigl + * @version 1 (28.10.23) + */ + public record KeyEnvironmentContainer(WeakReference> env, + BiMap mapProof + ) { + + public KeyEnvironmentContainer(KeYEnvironment env) { + this(new WeakReference<>(env), HashBiMap.create(1)); + } + + void dispose() { + env.clear(); + mapProof.clear(); + } + } + + private record ProofContainer(WeakReference wProof, + BiMap> mapNode, + BiMap> mapTreeNode, + BiMap mapGoalText + ) { + public ProofContainer(Proof proof) { + this(new WeakReference<>(proof), HashBiMap.create(16), HashBiMap.create(16), HashBiMap.create(16)); + } + + void dispose() { + mapNode.clear(); + } + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java index 74c2d9d1cc4..b0c2397d1f3 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java @@ -1,8 +1,15 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record MacroStatistic() { +public record MacroStatistic(KeyIdentifications.ProofId proofId, String macroId, boolean cancelled, int appliedRules, + int closedGoals) { + public static MacroStatistic from(KeyIdentifications.ProofId proofId, ProofMacroFinishedInfo info) { + return new MacroStatistic(proofId, info.getMacro().getName(), info.isCancelled(), + info.getAppliedRules(), info.getClosedGoals()); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java index 9bc8ad0cd04..9e24e0f4cd7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -1,8 +1,18 @@ package org.keyproject.key.api.data; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record NodeDesc() { +public record NodeDesc(KeyIdentifications.NodeId nodeid, String branchLabel, + boolean scriptRuleApplication, + @Nullable List children +) { + public NodeDesc(KeyIdentifications.ProofId proofId, int serialNr, String branchLabel, boolean scriptRuleApplication) { + this(new KeyIdentifications.NodeId(proofId, serialNr), branchLabel, scriptRuleApplication, null); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java deleted file mode 100644 index 3d4893d43e4..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.data; - -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record PrintId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java new file mode 100644 index 00000000000..31981c61beb --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java @@ -0,0 +1,14 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.macros.ProofMacro; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record ProofMacroDesc(String name, String category, String description, String scriptCommandName) { + public static ProofMacroDesc from(ProofMacro proofMacro) { + return new ProofMacroDesc(proofMacro.getName(), proofMacro.getCategory(), + proofMacro.getDescription(), proofMacro.getScriptCommandName()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java new file mode 100644 index 00000000000..f6eef733d08 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java @@ -0,0 +1,13 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record ProofScriptCommandDesc() { + public static ProofScriptCommandDesc from(ProofScriptCommand proofScriptCommand) { + return null; + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java index b582b4a73f5..66df02ee6b0 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -1,8 +1,19 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.logic.sort.Sort; + +import java.util.List; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record SortDesc() { +public record SortDesc(String string, String documentation, + List extendsSorts, + boolean anAbstract, String s) { + public static SortDesc from(Sort sort) { + return new SortDesc(sort.name().toString(), sort.getDocumentation(), + sort.extendsSorts().stream().map(SortDesc::from).toList(), + sort.isAbstract(), sort.declarationString()); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java deleted file mode 100644 index b69046120f5..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.data; - -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record TermAction(TermActionId commandId, String displayName) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java new file mode 100644 index 00000000000..b27ac08a279 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java @@ -0,0 +1,11 @@ +package org.keyproject.key.api.data; + +import org.keyproject.key.api.data.KeyIdentifications.TermActionId; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TermActionDesc(TermActionId commandId, String displayName, String description, String category, + TermActionKind kind) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java index 7951c776af4..96d22acee47 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java @@ -1,8 +1,2 @@ package org.keyproject.key.api.data; -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record TermActionId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java new file mode 100644 index 00000000000..cc7d9aec71a --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public enum TermActionKind { + BuiltIn, Script, Macro, Taclet +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java index 3dba5cc492e..96d22acee47 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java @@ -1,8 +1,2 @@ package org.keyproject.key.api.data; -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record TreeNodeId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java new file mode 100644 index 00000000000..5750fea944d --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java @@ -0,0 +1,12 @@ +package org.keyproject.key.api.internal; + +import de.uka.ilkd.key.pp.InitialPositionTable; +import de.uka.ilkd.key.pp.PositionTable; +import de.uka.ilkd.key.proof.Node; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record NodeText(String text, InitialPositionTable table) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java index e82ca44ae28..e84a0152760 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java @@ -1,11 +1,10 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.ContractDesc; +import org.keyproject.key.api.data.FunctionDesc; +import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.SortDesc; import java.util.List; @@ -18,14 +17,14 @@ @JsonSegment("env") public interface EnvApi { @JsonRequest - CompletableFuture> sorts(KeYEnvironment env); + CompletableFuture> sorts(EnvironmentId env); @JsonRequest - CompletableFuture> functions(KeYEnvironment env); + CompletableFuture> functions(EnvironmentId env); @JsonRequest - CompletableFuture> contracts(KeYEnvironment env); + CompletableFuture> contracts(EnvironmentId env); @JsonRequest - CompletableFuture openContract(KeYEnvironment env, String contractId); + CompletableFuture openContract(ContractId contractId); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java index fe678b8f04e..2f34293f0d5 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -1,13 +1,12 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.proof.Node; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.data.GoalText; -import org.keyproject.key.api.data.PrintId; -import org.keyproject.key.api.data.TermAction; -import org.keyproject.key.api.data.TermActionId; +import org.keyproject.key.api.NodeTextDesc; +import org.keyproject.key.api.NodeTextId; +import org.keyproject.key.api.data.*; +import org.keyproject.key.api.data.KeyIdentifications.*; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -19,14 +18,14 @@ @JsonSegment("goal") public interface GoalApi { @JsonRequest - CompletableFuture print(Node id); + CompletableFuture print(NodeId id, PrintOptions options); @JsonRequest - CompletableFuture> actions(PrintId id, int pos); + CompletableFuture> actions(NodeTextId id, int pos); @JsonRequest("apply_action") - CompletableFuture> applyAction(TermActionId id); + CompletableFuture> applyAction(TermActionId id); @JsonNotification("free") - void freePrint(PrintId id); + void freePrint(NodeTextId id); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index ac650359a74..56a166f9af7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -3,5 +3,5 @@ /** * The combined interface that is provided by KeY. */ -public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi { +public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi, ProofLoadApi{ } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java index a4a16b66b02..f101a47f16a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java @@ -1,12 +1,13 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.macros.ProofMacro; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.ProofMacroDesc; +import org.keyproject.key.api.data.ProofScriptCommandDesc; import java.util.List; import java.util.concurrent.CompletableFuture; +import org.keyproject.key.api.data.KeyIdentifications.*; @JsonSegment("meta") public interface MetaApi { @@ -14,8 +15,8 @@ public interface MetaApi { CompletableFuture getVersion(); @JsonRequest("available_macros") - CompletableFuture> getAvailableMacros(); + CompletableFuture> getAvailableMacros(); @JsonRequest("available_script_commands") - CompletableFuture>> getAvailableScriptCommands(); + CompletableFuture> getAvailableScriptCommands(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java new file mode 100644 index 00000000000..6555b2a16fb --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.remoteapi; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record PrintOptions(boolean unicode, int width, int indentation, boolean pure, + boolean termLabels) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java index 16c9f390b89..e496b7a4d38 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java @@ -1,9 +1,8 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.proof.Node; -import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.Statistics; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.MacroStatistic; import org.keyproject.key.api.data.NodeDesc; import org.keyproject.key.api.data.StreategyOptions; @@ -17,32 +16,32 @@ */ public interface ProofApi { @JsonRequest - CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options); + CompletableFuture script(ProofId proof, String scriptLine, StreategyOptions options); @JsonRequest - CompletableFuture macro(Proof proof, String macroId, StreategyOptions options); + CompletableFuture macro(ProofId proof, String macroId, StreategyOptions options); @JsonRequest - CompletableFuture auto(Proof proof, StreategyOptions options); + CompletableFuture auto(ProofId proof, StreategyOptions options); @JsonRequest - CompletableFuture dispose(Proof proof); + CompletableFuture dispose(ProofId proof); @JsonRequest - CompletableFuture goals(Proof proof); + CompletableFuture> goals(ProofId proof, boolean onlyOpened, boolean onlyEnabled); @JsonRequest - CompletableFuture tree(Proof proof); + CompletableFuture tree(ProofId proof); @JsonRequest - CompletableFuture root(Proof proof); + CompletableFuture root(ProofId proof); @JsonRequest - CompletableFuture> children(Proof proof, Node nodeId); + CompletableFuture> children(NodeId nodeId); @JsonRequest - CompletableFuture> pruneTo(Proof proof, Node nodeId); + CompletableFuture> pruneTo(NodeId nodeId); @JsonRequest - CompletableFuture statistics(Proof proof); + CompletableFuture statistics(ProofId proof); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java similarity index 50% rename from keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java index 14d737fd5d6..9ffedadf57d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java @@ -1,10 +1,16 @@ -package org.keyproject.key.api.data; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.KeyIdentifications; +import org.keyproject.key.api.data.KeyIdentifications.EnvironmentId; +import org.keyproject.key.api.data.KeyIdentifications.ProofId; +import org.keyproject.key.api.data.LoadParams; +import org.keyproject.key.api.data.ProblemDefinition; import java.util.concurrent.CompletableFuture; @@ -15,20 +21,29 @@ * @since v1 */ @JsonSegment("loading") -public interface ProofLoading { +public interface ProofLoadApi { /** * I am not sure whether this is helpful. Mainly a feature for testing?! * @param id * @return */ @JsonRequest - CompletableFuture loadExample(String id); + CompletableFuture loadExample(String id); /** * */ @JsonRequest - CompletableFuture loadProblem(ProblemDefinition problem); + CompletableFuture loadProblem(ProblemDefinition problem); + + /** + * + */ + @JsonRequest + CompletableFuture loadKey(String content); + + @JsonRequest + CompletableFuture loadTerm(String term); /** * Test! @@ -38,5 +53,5 @@ public interface ProofLoading { * @throws ProblemLoaderException if something went wrong */ @JsonRequest - CompletableFuture> load(LoadParams params) throws ProblemLoaderException; + CompletableFuture> load(LoadParams params) throws ProblemLoaderException; } \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java index 88f5cad0330..d3225919d63 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java @@ -1,10 +1,10 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.KeyIdentifications.ProofId; +import org.keyproject.key.api.data.KeyIdentifications.TreeNodeId; import org.keyproject.key.api.data.TreeNodeDesc; -import org.keyproject.key.api.data.TreeNodeId; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -16,11 +16,11 @@ @JsonSegment("proofTree") public interface ProofTreeApi { @JsonRequest("root") - CompletableFuture treeRoot(Proof id); + CompletableFuture treeRoot(ProofId id); @JsonRequest("children") - CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId); + CompletableFuture> treeChildren(ProofId proof, TreeNodeId nodeId); @JsonRequest("subtree") - CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId); + CompletableFuture> treeSubtree(ProofId proof, TreeNodeId nodeId); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java index a7aebdca1bf..ca086eae72f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -1,5 +1,7 @@ package org.keyproject.key.api.remoteclient; +import de.uka.ilkd.key.prover.TaskFinishedInfo; +import de.uka.ilkd.key.prover.TaskStartedInfo; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; @@ -61,5 +63,10 @@ public interface ClientApi { */ @JsonRequest CompletableFuture showDocument(ShowDocumentParams params); + + + void taskFinished(TaskFinishedInfo info); + void taskProgress(int position); + void taskStarted(TaskStartedInfo info); //endregion } diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java index 1b63674ce67..b275265b6c7 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -1,5 +1,7 @@ package org.keyproject.key.api; +import de.uka.ilkd.key.prover.TaskFinishedInfo; +import de.uka.ilkd.key.prover.TaskStartedInfo; import org.keyproject.key.api.remoteclient.*; import javax.annotation.Nullable; @@ -32,4 +34,19 @@ public CompletableFuture userResponse(ShowMessageRequestParam public CompletableFuture showDocument(ShowDocumentParams params) { return null; } + + @Override + public void taskFinished(TaskFinishedInfo info) { + System.out.println(info); + } + + @Override + public void taskProgress(int position) { + + } + + @Override + public void taskStarted(TaskStartedInfo info) { + System.out.println(info); + } } diff --git a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index edbe4aee393..ae34b339231 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.keyproject.key.api.adapters.KeyAdapter; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; @@ -24,7 +25,7 @@ public class TestRpc { private KeyApi keyApi; @BeforeEach - void setup() throws IOException, ExecutionException, InterruptedException, TimeoutException { + void setup() throws IOException { PipedInputStream inClient = new PipedInputStream(); PipedOutputStream outClient = new PipedOutputStream(); PipedInputStream inServer = new PipedInputStream(); @@ -33,7 +34,9 @@ void setup() throws IOException, ExecutionException, InterruptedException, Timeo inClient.connect(outServer); outClient.connect(inServer); - Launcher serverLauncher = StartServer.launch(outServer, inServer); + KeyApiImpl impl = new KeyApiImpl(new KeyAdapter(null)); + Launcher serverLauncher = StartServer.launch(outServer, inServer, impl); + impl.setClientApi(serverLauncher.getRemoteProxy()); var client = new SimpleClient(); Launcher clientLauncher = new Launcher.Builder() diff --git a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java index 8b8f69d3bf3..5d7647eaf34 100644 --- a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java +++ b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java @@ -3,8 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.exploration; -import java.io.File; - import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.nparser.KeyIO; @@ -12,13 +10,13 @@ import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; - -import org.key_project.util.collection.ImmutableList; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.key_project.util.collection.ImmutableList; + +import java.io.File; import static org.junit.jupiter.api.Assertions.*; @@ -85,7 +83,7 @@ public void testAdditionAntec() { assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -127,7 +125,7 @@ public void testAdditionSucc() { testAddition(withAddedTerm, justification, added, false); assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -148,9 +146,9 @@ public void testChangeFormula() { assertSame(1, goals.size(), "Prerequisite for test"); Sequent sequent = goals.head().node().sequent(); PosInOccurrence pio = - new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); + new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); expService.applyChangeFormula(goals.head(), pio, sequent.succedent().get(0).formula(), - change); + change); ImmutableList newCreatedGoals = currentProof.openGoals(); assertEquals(2, newCreatedGoals.size(), "Two new goals created"); @@ -168,13 +166,16 @@ public void testChangeFormula() { assertNotNull(justificationBranch.node().lookup(ExplorationNodeData.class)); assertEquals(new Name("hide_right"), hideNode.getAppliedRuleApp().rule().name(), - "Hide Right was applied"); + "Hide Right was applied"); // set all goals to interactive justificationBranch.setEnabled(true); // perform proof, it has to close - env.getProofControl().startAndWaitForAutoMode(currentProof, newCreatedGoals); - assertTrue(currentProof.closed(), "Proof is closed"); - + try { + env.getProofControl().startAndWaitForAutoMode(currentProof, newCreatedGoals); + assertTrue(currentProof.closed(), "Proof is closed"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } @@ -183,34 +184,34 @@ public void testChangeFormula() { */ private void testAddition(Goal withAddedTerm, Goal justification, Term added, boolean antec) { Semisequent semiSeqAdded = - antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfAdded = - antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); Semisequent semiSeqUntouched = - !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfUntouched = - !antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + !antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); assertSame(semiSeqAdded.size(), parentSemiSeqOfAdded.size() + 1, - "The size of the added semisequent has changed"); + "The size of the added semisequent has changed"); assertEquals(semiSeqAdded.get(0).formula(), added, "Added Term is indeed added"); assertFalse(justification.isAutomatic(), "Justification branch is marked as interactive"); assertSame(semiSeqUntouched.size(), parentSemiSeqOfUntouched.size(), - "The size if untouched semisequents is the same"); + "The size if untouched semisequents is the same"); assertEquals(semiSeqUntouched, parentSemiSeqOfUntouched, - "The untouched semisequents are equal"); + "The untouched semisequents are equal"); Node parent = withAddedTerm.node().parent(); assertEquals(parent, justification.node().parent(), "Both nodes have the same parent"); assertEquals(new Name("cut"), parent.getAppliedRuleApp().rule().name(), - "The addition was inserted using the cut rule"); + "The addition was inserted using the cut rule"); } /** From e76f27be403d489cfe5d48e78c766eb3b9adb8b2 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 29 Oct 2023 22:44:19 +0100 Subject: [PATCH 06/50] more doc and py generation --- api.meta.json | 1144 +++++++++++++++++ api.meta.md | 480 +++++++ api.py | 374 ++++++ .../main/java/de/uka/ilkd/key/proof/Node.java | 1 + keyext.api.doc/build.gradle | 1 + keyext.api.doc/src/main/java/DocGen.java | 189 +++ .../src/main/java/ExtractMetaData.java | 343 +++-- keyext.api.doc/src/main/java/Metamodel.java | 93 ++ keyext.api.doc/src/main/java/PyGen.java | 136 ++ keyext.api/build.gradle | 6 +- .../org/keyproject/key/api/KeyApiImpl.java | 17 +- .../org/keyproject/key/api/NodeTextDesc.java | 8 - .../org/keyproject/key/api/NodeTextId.java | 6 - .../keyproject/key/api/TermActionUtil.java | 3 +- .../key/api/data/KeyIdentifications.java | 8 +- .../org/keyproject/key/api/data/NodeDesc.java | 5 +- .../keyproject/key/api/data/NodeTextDesc.java | 9 + .../key/api/data/ProblemDefinition.java | 3 +- .../keyproject/key/api/data/TermActionId.java | 2 - .../keyproject/key/api/data/TreeNodeId.java | 2 - .../key/api/remoteapi/ExampleApi.java | 2 +- .../key/api/remoteapi/ExampleDesc.java | 13 + .../keyproject/key/api/remoteapi/GoalApi.java | 3 +- .../key/api/remoteapi/ServerManagement.java | 2 +- keyext.api/src/main/python/keyapi/rpc.py | 76 -- .../java/org/keyproject/key/api/TestRpc.java | 6 +- .../keyapi/__init__.py | 11 +- keyext.client.python/keyapi/rpc.py | 200 +++ .../python => keyext.client.python}/main.py | 0 keyext.client.python/rwtest.py | 402 ++++++ 30 files changed, 3302 insertions(+), 243 deletions(-) create mode 100644 api.meta.json create mode 100644 api.meta.md create mode 100644 api.py create mode 100644 keyext.api.doc/src/main/java/DocGen.java create mode 100644 keyext.api.doc/src/main/java/Metamodel.java create mode 100644 keyext.api.doc/src/main/java/PyGen.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java delete mode 100644 keyext.api/src/main/python/keyapi/rpc.py rename {keyext.api/src/main/python => keyext.client.python}/keyapi/__init__.py (54%) create mode 100644 keyext.client.python/keyapi/rpc.py rename {keyext.api/src/main/python => keyext.client.python}/main.py (100%) create mode 100644 keyext.client.python/rwtest.py diff --git a/api.meta.json b/api.meta.json new file mode 100644 index 00000000000..180b16a3019 --- /dev/null +++ b/api.meta.json @@ -0,0 +1,1144 @@ +{ + "endpoints": [ + { + "name": "examples/list", + "documentation": "", + "args": [], + "returnType": { + "type": { + "typeName": "ExampleDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "meta/version", + "documentation": "", + "args": [], + "returnType": "STRING" + }, + { + "name": "meta/available_script_commands", + "documentation": "", + "args": [], + "returnType": { + "type": { + "typeName": "ProofScriptCommandDesc", + "fields": [], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "meta/available_macros", + "documentation": "", + "args": [], + "returnType": { + "type": { + "typeName": "ProofMacroDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "scriptCommandName", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "server/exit", + "documentation": "", + "args": [] + }, + { + "name": "server/shutdown", + "documentation": "", + "args": [], + "returnType": "BOOL" + }, + { + "name": "server/setTrace", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "SetTraceParams" + } + ] + }, + { + "name": "proofTree/root", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProofId" + } + ], + "returnType": { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + } + }, + { + "name": "proofTree/children", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProofId" + }, + { + "name": "arg1", + "type": "TreeNodeId" + } + ], + "returnType": { + "type": { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "proofTree/subtree", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProofId" + }, + { + "name": "arg1", + "type": "TreeNodeId" + } + ], + "returnType": { + "type": { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "goal/print", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "NodeId" + }, + { + "name": "arg1", + "type": "PrintOptions" + } + ], + "returnType": { + "typeName": "NodeTextDesc", + "fields": [ + { + "name": "id", + "type": "NodeTextId" + }, + { + "name": "result", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "goal/actions", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "NodeTextId" + }, + { + "name": "arg1", + "type": "INT" + } + ], + "returnType": { + "type": { + "typeName": "TermActionDesc", + "fields": [ + { + "name": "commandId", + "type": "TermActionId" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "kind", + "type": "TermActionKind" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "goal/apply_action", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "TermActionId" + } + ], + "returnType": { + "type": { + "typeName": "TermActionDesc", + "fields": [ + { + "name": "commandId", + "type": "TermActionId" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "kind", + "type": "TermActionKind" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "goal/free", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "NodeTextId" + } + ] + }, + { + "name": "env/functions", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "EnvironmentId" + } + ], + "returnType": { + "type": { + "typeName": "FunctionDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "sort", + "type": "STRING" + }, + { + "name": "retSort", + "type": "SortDesc" + }, + { + "name": "argSorts", + "type": "List" + }, + { + "name": "rigid", + "type": "BOOL" + }, + { + "name": "unique", + "type": "BOOL" + }, + { + "name": "skolemConstant", + "type": "BOOL" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "env/sorts", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "EnvironmentId" + } + ], + "returnType": { + "type": { + "typeName": "SortDesc", + "fields": [ + { + "name": "string", + "type": "STRING" + }, + { + "name": "documentation", + "type": "STRING" + }, + { + "name": "extendsSorts", + "type": "List" + }, + { + "name": "anAbstract", + "type": "BOOL" + }, + { + "name": "s", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "env/contracts", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "EnvironmentId" + } + ], + "returnType": { + "type": { + "typeName": "ContractDesc", + "fields": [ + { + "name": "contractId", + "type": "ContractId" + }, + { + "name": "name", + "type": "STRING" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "typeName", + "type": "STRING" + }, + { + "name": "htmlText", + "type": "STRING" + }, + { + "name": "plainText", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "env/openContract", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ContractId" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/load", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "LoadParams" + } + ], + "returnType": { + "a": { + "typeName": "EnvironmentId", + "fields": [ + { + "name": "envId", + "type": "STRING" + } + ], + "documentation": "" + }, + "b": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "loading/loadKey", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/loadExample", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/loadProblem", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProblemDefinition" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/loadTerm", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "client/sayHello", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ] + }, + { + "name": "client/logTrace", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "LogTraceParams" + } + ] + }, + { + "name": "client/sm", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ShowMessageParams" + } + ] + }, + { + "name": "client/userResponse", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ShowMessageRequestParams" + } + ], + "returnType": { + "typeName": "MessageActionItem", + "fields": [ + { + "name": "title", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "client/showDocument", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ShowDocumentParams" + } + ], + "returnType": { + "typeName": "ShowDocumentResult", + "fields": [ + { + "name": "success", + "type": "BOOL" + } + ], + "documentation": "" + } + } + ], + "types": [ + { + "typeName": "ExampleDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "ProofScriptCommandDesc", + "fields": [], + "documentation": "" + }, + { + "typeName": "ProofMacroDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "scriptCommandName", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TraceValue", + "values": [ + "Off", + "Message", + "All" + ], + "documentation": "" + }, + { + "typeName": "SetTraceParams", + "fields": [ + { + "name": "value", + "type": "TraceValue" + } + ], + "documentation": "" + }, + { + "typeName": "EnvironmentId", + "fields": [ + { + "name": "envId", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + }, + { + "typeName": "TreeNodeId", + "fields": [ + { + "name": "id", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "NodeId", + "fields": [ + { + "name": "proofId", + "type": "ProofId" + }, + { + "name": "nodeId", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "PrintOptions", + "fields": [ + { + "name": "unicode", + "type": "BOOL" + }, + { + "name": "width", + "type": "INT" + }, + { + "name": "indentation", + "type": "INT" + }, + { + "name": "pure", + "type": "BOOL" + }, + { + "name": "termLabels", + "type": "BOOL" + } + ], + "documentation": "" + }, + { + "typeName": "NodeTextId", + "fields": [ + { + "name": "nodeId", + "type": "NodeId" + }, + { + "name": "nodeTextId", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "NodeTextDesc", + "fields": [ + { + "name": "id", + "type": "NodeTextId" + }, + { + "name": "result", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TermActionId", + "fields": [ + { + "name": "nodeId", + "type": "NodeId" + }, + { + "name": "pio", + "type": "STRING" + }, + { + "name": "id", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TermActionKind", + "values": [ + "BuiltIn", + "Script", + "Macro", + "Taclet" + ], + "documentation": "" + }, + { + "typeName": "TermActionDesc", + "fields": [ + { + "name": "commandId", + "type": "TermActionId" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "kind", + "type": "TermActionKind" + } + ], + "documentation": "" + }, + { + "typeName": "List", + "fields": [], + "documentation": "" + }, + { + "typeName": "SortDesc", + "fields": [ + { + "name": "string", + "type": "STRING" + }, + { + "name": "documentation", + "type": "STRING" + }, + { + "name": "extendsSorts", + "type": "List" + }, + { + "name": "anAbstract", + "type": "BOOL" + }, + { + "name": "s", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "FunctionDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "sort", + "type": "STRING" + }, + { + "name": "retSort", + "type": "SortDesc" + }, + { + "name": "argSorts", + "type": "List" + }, + { + "name": "rigid", + "type": "BOOL" + }, + { + "name": "unique", + "type": "BOOL" + }, + { + "name": "skolemConstant", + "type": "BOOL" + } + ], + "documentation": "" + }, + { + "typeName": "ContractId", + "fields": [ + { + "name": "envId", + "type": "EnvironmentId" + }, + { + "name": "contractId", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "ContractDesc", + "fields": [ + { + "name": "contractId", + "type": "ContractId" + }, + { + "name": "name", + "type": "STRING" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "typeName", + "type": "STRING" + }, + { + "name": "htmlText", + "type": "STRING" + }, + { + "name": "plainText", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "LoadParams", + "fields": [ + { + "name": "keyFile", + "type": "STRING" + }, + { + "name": "javaFile", + "type": "STRING" + }, + { + "name": "classPath", + "type": "List" + }, + { + "name": "bootClassPath", + "type": "STRING" + }, + { + "name": "includes", + "type": "List" + } + ], + "documentation": "" + }, + { + "typeName": "ProblemDefinition", + "fields": [ + { + "name": "sorts", + "type": "List" + }, + { + "name": "functions", + "type": "List" + }, + { + "name": "predicates", + "type": "List" + }, + { + "name": "antecTerms", + "type": "List" + }, + { + "name": "succTerms", + "type": "List" + } + ], + "documentation": "" + }, + { + "typeName": "LogTraceParams", + "fields": [ + { + "name": "messag", + "type": "STRING" + }, + { + "name": "verbose", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "MessageType", + "values": [ + "Unused", + "Error", + "Warning", + "Info", + "Log", + "Debug" + ], + "documentation": "" + }, + { + "typeName": "ShowMessageParams", + "fields": [ + { + "name": "type", + "type": "MessageType" + }, + { + "name": "message", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "MessageActionItem[]", + "fields": [], + "documentation": "" + }, + { + "typeName": "ShowMessageRequestParams", + "fields": [ + { + "name": "type", + "type": "MessageType" + }, + { + "name": "message", + "type": "STRING" + }, + { + "name": "actions", + "type": "MessageActionItem[]" + } + ], + "documentation": "" + }, + { + "typeName": "MessageActionItem", + "fields": [ + { + "name": "title", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "Range", + "fields": [ + { + "name": "start", + "type": "INT" + }, + { + "name": "end", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "ShowDocumentParams", + "fields": [ + { + "name": "uri", + "type": "STRING" + }, + { + "name": "external", + "type": "BOOL" + }, + { + "name": "takeFocus", + "type": "BOOL" + }, + { + "name": "selection", + "type": "Range" + } + ], + "documentation": "" + }, + { + "typeName": "ShowDocumentResult", + "fields": [ + { + "name": "success", + "type": "BOOL" + } + ], + "documentation": "" + }, + { + "typeName": "TaskFinishedInfo", + "fields": [], + "documentation": "" + }, + { + "typeName": "TaskStartedInfo", + "fields": [], + "documentation": "" + } + ] +} \ No newline at end of file diff --git a/api.meta.md b/api.meta.md new file mode 100644 index 00000000000..f53d88619f3 --- /dev/null +++ b/api.meta.md @@ -0,0 +1,480 @@ +## Types +### Type: ContractDesc +``` +type ContractDesc { + contractId : ContractId + displayName : STRING + htmlText : STRING + name : STRING + plainText : STRING + typeName : STRING +} +``` + +### Type: ContractId +``` +type ContractId { + contractId : INT + envId : EnvironmentId +} +``` + +### Type: EnvironmentId +``` +type EnvironmentId { + envId : STRING +} +``` + +### Type: ExampleDesc +``` +type ExampleDesc { + description : STRING + name : STRING +} +``` + +### Type: FunctionDesc +``` +type FunctionDesc { + argSorts : List + name : STRING + retSort : SortDesc + rigid : BOOL + skolemConstant : BOOL + sort : STRING + unique : BOOL +} +``` + +### Type: List +``` +type List { + +} +``` + +### Type: LoadParams +``` +type LoadParams { + bootClassPath : STRING + classPath : List + includes : List + javaFile : STRING + keyFile : STRING +} +``` + +### Type: LogTraceParams +``` +type LogTraceParams { + messag : STRING + verbose : STRING +} +``` + +### Type: MessageActionItem +``` +type MessageActionItem { + title : STRING +} +``` + +### Type: MessageActionItem[] +``` +type MessageActionItem[] { + +} +``` + +### Type: MessageType +``` +enum MessageType { Unused, Error, Warning, Info, Log, Debug } +``` + +### Type: NodeId +``` +type NodeId { + nodeId : INT + proofId : ProofId +} +``` + +### Type: NodeTextDesc +``` +type NodeTextDesc { + id : NodeTextId + result : STRING +} +``` + +### Type: NodeTextId +``` +type NodeTextId { + nodeId : NodeId + nodeTextId : INT +} +``` + +### Type: PrintOptions +``` +type PrintOptions { + indentation : INT + pure : BOOL + termLabels : BOOL + unicode : BOOL + width : INT +} +``` + +### Type: ProblemDefinition +``` +type ProblemDefinition { + antecTerms : List + functions : List + predicates : List + sorts : List + succTerms : List +} +``` + +### Type: ProofId +``` +type ProofId { + env : EnvironmentId + proofId : STRING +} +``` + +### Type: ProofMacroDesc +``` +type ProofMacroDesc { + category : STRING + description : STRING + name : STRING + scriptCommandName : STRING +} +``` + +### Type: ProofScriptCommandDesc +``` +type ProofScriptCommandDesc { + +} +``` + +### Type: Range +``` +type Range { + end : INT + start : INT +} +``` + +### Type: SetTraceParams +``` +type SetTraceParams { + value : TraceValue +} +``` + +### Type: ShowDocumentParams +``` +type ShowDocumentParams { + external : BOOL + selection : Range + takeFocus : BOOL + uri : STRING +} +``` + +### Type: ShowDocumentResult +``` +type ShowDocumentResult { + success : BOOL +} +``` + +### Type: ShowMessageParams +``` +type ShowMessageParams { + message : STRING + type : MessageType +} +``` + +### Type: ShowMessageRequestParams +``` +type ShowMessageRequestParams { + actions : MessageActionItem[] + message : STRING + type : MessageType +} +``` + +### Type: SortDesc +``` +type SortDesc { + anAbstract : BOOL + documentation : STRING + extendsSorts : List + s : STRING + string : STRING +} +``` + +### Type: TaskFinishedInfo +``` +type TaskFinishedInfo { + +} +``` + +### Type: TaskStartedInfo +``` +type TaskStartedInfo { + +} +``` + +### Type: TermActionDesc +``` +type TermActionDesc { + category : STRING + commandId : TermActionId + description : STRING + displayName : STRING + kind : TermActionKind +} +``` + +### Type: TermActionId +``` +type TermActionId { + id : STRING + nodeId : NodeId + pio : STRING +} +``` + +### Type: TermActionKind +``` +enum TermActionKind { BuiltIn, Script, Macro, Taclet } +``` + +### Type: TraceValue +``` +enum TraceValue { Off, Message, All } +``` + +### Type: TreeNodeDesc +``` +type TreeNodeDesc { + +} +``` + +### Type: TreeNodeId +``` +type TreeNodeId { + id : STRING +} +``` + +## Endpoints +### client/logTrace (`server ~~> client`) + +``` +Client.client/logTrace( arg0 : LogTraceParams ) **async** +``` + + +### client/sayHello (`server ~~> client`) + +``` +Client.client/sayHello( arg0 : STRING ) **async** +``` + + +### client/showDocument (`server -> client`) + +``` +Client.client/showDocument( arg0 : ShowDocumentParams ) -> ShowDocumentResult +``` + + +### client/sm (`server ~~> client`) + +``` +Client.client/sm( arg0 : ShowMessageParams ) **async** +``` + + +### client/userResponse (`server -> client`) + +``` +Client.client/userResponse( arg0 : ShowMessageRequestParams ) -> MessageActionItem +``` + + +### env/contracts (`client -> server`) + +``` +Server.env/contracts( arg0 : EnvironmentId ) -> ContractDesc[] +``` + + +### env/functions (`client -> server`) + +``` +Server.env/functions( arg0 : EnvironmentId ) -> FunctionDesc[] +``` + + +### env/openContract (`client -> server`) + +``` +Server.env/openContract( arg0 : ContractId ) -> ProofId +``` + + +### env/sorts (`client -> server`) + +``` +Server.env/sorts( arg0 : EnvironmentId ) -> SortDesc[] +``` + + +### examples/list (`client -> server`) + +``` +Server.examples/list( ) -> ExampleDesc[] +``` + + +### goal/actions (`client -> server`) + +``` +Server.goal/actions( arg0 : NodeTextId, arg1 : INT ) -> TermActionDesc[] +``` + + +### goal/apply_action (`client -> server`) + +``` +Server.goal/apply_action( arg0 : TermActionId ) -> TermActionDesc[] +``` + + +### goal/free (`client ~~> server`) + +``` +Server.goal/free( arg0 : NodeTextId ) **async** +``` + + +### goal/print (`client -> server`) + +``` +Server.goal/print( arg0 : NodeId, arg1 : PrintOptions ) -> NodeTextDesc +``` + + +### loading/load (`client -> server`) + +``` +Server.loading/load( arg0 : LoadParams ) -> either +``` + + +### loading/loadExample (`client -> server`) + +``` +Server.loading/loadExample( arg0 : STRING ) -> ProofId +``` + + +### loading/loadKey (`client -> server`) + +``` +Server.loading/loadKey( arg0 : STRING ) -> ProofId +``` + + +### loading/loadProblem (`client -> server`) + +``` +Server.loading/loadProblem( arg0 : ProblemDefinition ) -> ProofId +``` + + +### loading/loadTerm (`client -> server`) + +``` +Server.loading/loadTerm( arg0 : STRING ) -> ProofId +``` + + +### meta/available_macros (`client -> server`) + +``` +Server.meta/available_macros( ) -> ProofMacroDesc[] +``` + + +### meta/available_script_commands (`client -> server`) + +``` +Server.meta/available_script_commands( ) -> ProofScriptCommandDesc[] +``` + + +### meta/version (`client -> server`) + +``` +Server.meta/version( ) -> STRING +``` + + +### proofTree/children (`client -> server`) + +``` +Server.proofTree/children( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +``` + + +### proofTree/root (`client -> server`) + +``` +Server.proofTree/root( arg0 : ProofId ) -> TreeNodeDesc +``` + + +### proofTree/subtree (`client -> server`) + +``` +Server.proofTree/subtree( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +``` + + +### server/exit (`client ~~> server`) + +``` +Server.server/exit( ) **async** +``` + + +### server/setTrace (`client ~~> server`) + +``` +Server.server/setTrace( arg0 : SetTraceParams ) **async** +``` + + +### server/shutdown (`client -> server`) + +``` +Server.server/shutdown( ) -> BOOL +``` + + diff --git a/api.py b/api.py new file mode 100644 index 00000000000..c83050a763e --- /dev/null +++ b/api.py @@ -0,0 +1,374 @@ +import enum +import abc +import typing +class ExampleDesc: + """""" + + name : str + description : str + +class ProofScriptCommandDesc: + """""" + + +class ProofMacroDesc: + """""" + + name : str + category : str + description : str + scriptCommandName : str + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + +class SetTraceParams: + """""" + + value : TraceValue + +class EnvironmentId: + """""" + + envId : str + +class ProofId: + """""" + + env : EnvironmentId + proofId : str + +class TreeNodeDesc: + """""" + + +class TreeNodeId: + """""" + + id : str + +class NodeId: + """""" + + proofId : ProofId + nodeId : int + +class PrintOptions: + """""" + + unicode : bool + width : int + indentation : int + pure : bool + termLabels : bool + +class NodeTextId: + """""" + + nodeId : NodeId + nodeTextId : int + +class NodeTextDesc: + """""" + + id : NodeTextId + result : str + +class TermActionId: + """""" + + nodeId : NodeId + pio : str + id : str + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + +class TermActionDesc: + """""" + + commandId : TermActionId + displayName : str + description : str + category : str + kind : TermActionKind + +class List: + """""" + + +class SortDesc: + """""" + + string : str + documentation : str + extendsSorts : List + anAbstract : bool + s : str + +class FunctionDesc: + """""" + + name : str + sort : str + retSort : SortDesc + argSorts : List + rigid : bool + unique : bool + skolemConstant : bool + +class ContractId: + """""" + + envId : EnvironmentId + contractId : int + +class ContractDesc: + """""" + + contractId : ContractId + name : str + displayName : str + typeName : str + htmlText : str + plainText : str + +class LoadParams: + """""" + + keyFile : str + javaFile : str + classPath : List + bootClassPath : str + includes : List + +class ProblemDefinition: + """""" + + sorts : List + functions : List + predicates : List + antecTerms : List + succTerms : List + +class LogTraceParams: + """""" + + messag : str + verbose : str + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + +class ShowMessageParams: + """""" + + type : MessageType + message : str + +class MessageActionItem[]: + """""" + + +class ShowMessageRequestParams: + """""" + + type : MessageType + message : str + actions : MessageActionItem[] + +class MessageActionItem: + """""" + + title : str + +class Range: + """""" + + start : int + end : int + +class ShowDocumentParams: + """""" + + uri : str + external : bool + takeFocus : bool + selection : Range + +class ShowDocumentResult: + """""" + + success : bool + +class TaskFinishedInfo: + """""" + + +class TaskStartedInfo: + """""" + + +class KeyServer(): + def env_contracts(self, arg0 : EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self.rpc.call_sync("env/contracts", ) + + def env_functions(self, arg0 : EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self.rpc.call_sync("env/functions", ) + + def env_openContract(self, arg0 : ContractId) -> ProofId: + """""" + + return self.rpc.call_sync("env/openContract", ) + + def env_sorts(self, arg0 : EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self.rpc.call_sync("env/sorts", ) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self.rpc.call_sync("examples/list", ) + + def goal_actions(self, arg0 : NodeTextId, arg1 : int) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/actions", ) + + def goal_apply_action(self, arg0 : TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/apply_action", ) + + def goal_free(self, arg0 : NodeTextId): + """""" + + return self.rpc.call_async("goal/free", ) + + def goal_print(self, arg0 : NodeId, arg1 : PrintOptions) -> NodeTextDesc: + """""" + + return self.rpc.call_sync("goal/print", ) + + def loading_load(self, arg0 : LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self.rpc.call_sync("loading/load", ) + + def loading_loadExample(self, arg0 : str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadExample", ) + + def loading_loadKey(self, arg0 : str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadKey", ) + + def loading_loadProblem(self, arg0 : ProblemDefinition) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadProblem", ) + + def loading_loadTerm(self, arg0 : str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadTerm", ) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self.rpc.call_sync("meta/available_macros", ) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self.rpc.call_sync("meta/available_script_commands", ) + + def meta_version(self, ) -> STRING: + """""" + + return self.rpc.call_sync("meta/version", ) + + def proofTree_children(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/children", ) + + def proofTree_root(self, arg0 : ProofId) -> TreeNodeDesc: + """""" + + return self.rpc.call_sync("proofTree/root", ) + + def proofTree_subtree(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/subtree", ) + + def server_exit(self, ): + """""" + + return self.rpc.call_async("server/exit", ) + + def server_setTrace(self, arg0 : SetTraceParams): + """""" + + return self.rpc.call_async("server/setTrace", ) + + def server_shutdown(self, ) -> BOOL: + """""" + + return self.rpc.call_sync("server/shutdown", ) + +class Client(abc.AbcMeta): + @abstractmethod + def client_logTrace(self, arg0 : LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, arg0 : str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, arg0 : ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, arg0 : ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, arg0 : ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass + diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 06da529607f..95ba46fe7be 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -12,6 +12,7 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; +import java.util.stream.Stream; import de.uka.ilkd.key.logic.RenamingTable; import de.uka.ilkd.key.logic.Sequent; diff --git a/keyext.api.doc/build.gradle b/keyext.api.doc/build.gradle index f7aadd6467c..84a1789e01f 100644 --- a/keyext.api.doc/build.gradle +++ b/keyext.api.doc/build.gradle @@ -1,4 +1,5 @@ dependencies { + implementation(project(":keyext.api")) implementation("com.github.javaparser:javaparser-core:3.25.5") implementation("com.github.javaparser:javaparser-symbol-solver-core:3.25.5") } \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/DocGen.java b/keyext.api.doc/src/main/java/DocGen.java new file mode 100644 index 00000000000..36aed393607 --- /dev/null +++ b/keyext.api.doc/src/main/java/DocGen.java @@ -0,0 +1,189 @@ +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class DocGen implements Supplier { + private final Metamodel.KeyApi metamodel; + private PrintWriter out; + private final StringWriter target = new StringWriter(); + + public DocGen(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + printHeader(); + + out.format("## Types%n"); + metamodel.types() + .stream().sorted(Comparator.comparing(Metamodel.Type::name)) + .forEach(this::printType); + + out.format("## Endpoints%n"); + metamodel.endpoints() + .stream().sorted(Comparator.comparing(Metamodel.Endpoint::name)) + .forEach(this::endpoints); + printFooter(); + } + return target.toString(); + } + + private void printFooter() { + + } + + private void printHeader() { + + + } + + private void endpoints(Metamodel.Endpoint endpoint) { + //out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); + //out.println(getJavaDoc(typeDeclaration)); + //out.println("\n"); + + var direction = ""; + if (endpoint instanceof Metamodel.ServerRequest sr) + direction = "client -> server"; + else if (endpoint instanceof Metamodel.ClientRequest sr) + direction = "server -> client"; + else if (endpoint instanceof Metamodel.ServerNotification sr) + direction = "client ~~> server"; + else if (endpoint instanceof Metamodel.ClientNotification sr) + direction = "server ~~> client"; + + out.format("### %s (`%s`) %n%n", endpoint.name(), direction); + out.format("```%n"); + var args = endpoint.args(); + final var a = args.stream() + .map(it -> "%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining(", ")); + if (endpoint instanceof Metamodel.ServerRequest sr) { + out.format("Server.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); + } else if (endpoint instanceof Metamodel.ClientRequest sr) + out.format("Client.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); + else if (endpoint instanceof Metamodel.ServerNotification sr) + out.format("Server.%s( %s ) **async**%n", endpoint.name(), a); + else if (endpoint instanceof Metamodel.ClientNotification sr) + out.format("Client.%s( %s ) **async**%n", endpoint.name(), a); + out.format("```%n"); + + out.println(endpoint.documentation()); + out.println(); + } + + private void printType(Metamodel.Type type) { + out.format("### Type: %s%n", type.name()); + if (type instanceof Metamodel.ObjectType ot) { + out.format(""" + ``` + type %s { + %s + } + ``` + """.formatted(type.name(), + ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) + .map(it -> "\t%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining("\n")))); + } + + if (type instanceof Metamodel.EnumType et) { + out.format(""" + ``` + enum %s { %s } + ``` + """.formatted(type.name(), String.join(", ", et.values()) + )); + out.format(type.documentation()); + } + out.format(type.documentation()); + out.println(); + } + + /* + private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ + var annotationExpr = m.getAnnotationByName("JsonNotification").or( + () -> m.getAnnotationByName("JsonRequest")) + .orElseThrow(); + + var segment = getJsonSegment(td) + "/"; + String name = ""; + + if (annotationExpr.isMarkerAnnotationExpr()) { + name = m.getNameAsString(); + } else if (annotationExpr.isSingleMemberAnnotationExpr()) { + var sma = annotationExpr.asSingleMemberAnnotationExpr(); + name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); + } else { + var ne = annotationExpr.asNormalAnnotationExpr(); + for (MemberValuePair pair : ne.getPairs()) { + switch (pair.getName().asString()) { + case "value": + name = pair.getValue().asLiteralStringValueExpr().getValue(); + break; + case "useSegment": + if (!pair.getValue().asBooleanLiteralExpr().getValue()) { + segment = ""; + } + } + } + } + return segment + name; + } + + @Nonnull + private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ + if (typeDeclaration.getJavadoc().isPresent()) { + final var javadoc = typeDeclaration.getJavadoc().get(); + return javadoc.getDescription().toText() + + "\n\n" + + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) + .collect(Collectors.joining("\n")); + } + return ""; + } + + private static String type (MethodDeclaration method){ + if (method.getAnnotationByName("JsonNotification").isPresent()) + return "notification"; + if (method.getAnnotationByName("JsonRequest").isPresent()) + return "request"; + return ""; + } + + private static boolean isExported (MethodDeclaration method){ + return method.getAnnotationByName("JsonNotification").isPresent() + || method.getAnnotationByName("JsonRequest").isPresent(); + } + + private void printHeader () { + out.format("# KeY-API%n%n"); + } + + private void printFooter () { + } + + + /* + private static boolean hasJsonSegment(TypeDeclaration it) { + return it.getAnnotationByName("JsonSegment").isPresent(); + } + + private static String getJsonSegment(TypeDeclaration it) { + var ae = it.getAnnotationByName("JsonSegment").get(); + return ae.asSingleMemberAnnotationExpr().getMemberValue() + .asLiteralStringValueExpr().getValue(); + } + */ + +} + diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java index a9df59adef8..2855e390f75 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -1,25 +1,27 @@ -import com.github.javaparser.ParseResult; +import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.TypeDeclaration; -import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; -import com.github.javaparser.javadoc.JavadocBlockTag; -import com.github.javaparser.resolution.SymbolResolver; -import com.github.javaparser.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.resolution.typesolvers.TypeSolverBuilder; -import com.github.javaparser.utils.SourceRoot; - -import javax.annotation.Nonnull; -import java.io.FileWriter; +import com.google.gson.*; +import de.uka.ilkd.key.proof.Proof; +import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteclient.ClientApi; +import sun.misc.Unsafe; + +import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.*; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; +import java.util.*; +import java.util.concurrent.CompletableFuture; /** * @author Alexander Weigl @@ -28,135 +30,250 @@ public class ExtractMetaData { private static PrintWriter out; - public static void main(String[] args) throws IOException { - System.out.println("XXX" + Arrays.toString(args)); - ParserConfiguration config = new ParserConfiguration(); - config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); - /*config.setAttributeComments(true); - config.setLexicalPreservationEnabled(false); - config.setStoreTokens(false); - config.setIgnoreAnnotationsWhenAttributingComments(true); - config.setDoNotAssignCommentsPrecedingEmptyLines(true);*/ - //var root = Paths.get(args[0]); - TypeSolver typeSolver = new TypeSolverBuilder() - .withSourceCode("keyext.api/src/main/java") - .withSourceCode("key.core/src/main/java") - .withSourceCode("key.util/src/main/java") - .withCurrentJRE() - .build(); - SymbolResolver symbolResolver = new JavaSymbolSolver(typeSolver); - config.setSymbolResolver(symbolResolver); - var source = new SourceRoot(Paths.get("keyext.api", "src", "main", "java"), config); - var cu = source.tryToParse(); - var jsonSegment = Comparator.comparing(ExtractMetaData::getJsonSegment); - var segments = cu.stream().filter(ParseResult::isSuccessful) - .filter(it -> it.getResult().get().getPrimaryType().isPresent()) - .map(it -> it.getResult().get().getPrimaryType().get()) - .filter(ExtractMetaData::hasJsonSegment) - .sorted(jsonSegment) - .toList(); + private static final List endpoints = new LinkedList<>(); + private static final List types = new LinkedList<>(); + private static final Metamodel.KeyApi keyApi = new Metamodel.KeyApi(endpoints, types); - try (var out = new PrintWriter(new FileWriter("doc.md"))) { - ExtractMetaData.out = out; - printHeader(segments); - segments.forEach(ExtractMetaData::printDocumentation); - printFooter(segments); + public static void main(String[] args) { + for (Method method : KeyApi.class.getMethods()) { + addServerEndpoint(method); } - // "org.keyproject.key.api.remoteapi.KeyApi"; + for (Method method : ClientApi.class.getMethods()) { + addClientEndpoint(method); + } + + try { + Files.writeString(Paths.get("api.meta.json"), getGson().toJson(keyApi)); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + var n = new DocGen(keyApi); + Files.writeString(Paths.get("api.meta.md"), n.get()); + } catch (IOException e) { + e.printStackTrace(); + } + try { + var n = new PyGen(keyApi); + Files.writeString(Paths.get("api.py"), n.get()); + } catch (IOException e) { + e.printStackTrace(); + } } - private static void printDocumentation(TypeDeclaration typeDeclaration) { - out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); - out.println(getJavaDoc(typeDeclaration)); - out.println("\n"); + private static Gson getGson() { + return new GsonBuilder() + .setPrettyPrinting() + .registerTypeAdapter(Type.class, new JsonSerializer() { + @Override + public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject json = (JsonObject) context.serialize(src); + json.addProperty("kind", src.kind()); + return json; + } + }) + .create(); + } - for (MethodDeclaration method : typeDeclaration.getMethods()) { - if (!isExported(method)) continue; + private static void addServerEndpoint(Method method) { + var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); + if (jsonSegment == null) return; + var segment = jsonSegment.value(); - String callName = getCallName(method, typeDeclaration); + var req = method.getAnnotation(JsonRequest.class); + var resp = method.getAnnotation(JsonNotification.class); - out.format("### %s (type: %s) %n%n", callName, type(method)); + var args = translate(method.getParameters()); - out.println(getJavaDoc(method)); + if (req != null) { + var mn = callMethodName(method.getName(), segment, req.value(), req.useSegment()); - out.println(); + if (method.getReturnType() == Void.class) { + System.err.println("Found void as return type for a request! " + method); + return; + } + + var retType = getOrFindType(method.getGenericReturnType()); + Objects.requireNonNull(retType, "No retType found " + method.getGenericReturnType()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ServerRequest(mn, documentation, args, retType); + endpoints.add(mm); + return; + } + + if (resp != null) { + var mn = callMethodName(method.getName(), segment, resp.value(), resp.useSegment()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ServerNotification(mn, documentation, args); + endpoints.add(mm); + return; } + + throw new IllegalStateException(); } - private static String getCallName(MethodDeclaration m, TypeDeclaration td) { - var annotationExpr = m.getAnnotationByName("JsonNotification").or( - () -> m.getAnnotationByName("JsonRequest")) - .orElseThrow(); + private static String findDocumentation(Method method) { + // TODO get compilation, get type, find method, getJavaDocComment() + return ""; + } - var segment = getJsonSegment(td) + "/"; - String name = ""; + private static List translate(Parameter[] parameters) { + return Arrays.stream(parameters).map(ExtractMetaData::translate).toList(); + } - if (annotationExpr.isMarkerAnnotationExpr()) { - name = m.getNameAsString(); - } else if (annotationExpr.isSingleMemberAnnotationExpr()) { - var sma = annotationExpr.asSingleMemberAnnotationExpr(); - name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); - } else { - var ne = annotationExpr.asNormalAnnotationExpr(); - for (MemberValuePair pair : ne.getPairs()) { - switch (pair.getName().asString()) { - case "value": - name = pair.getValue().asLiteralStringValueExpr().getValue(); - break; - case "useSegment": - if (!pair.getValue().asBooleanLiteralExpr().getValue()) { - segment = ""; - } - } - } - } - return segment + name; + private static Metamodel.Argument translate(Parameter parameter) { + var type = getOrFindType(parameter.getType()).name(); + return new Metamodel.Argument(parameter.getName(), type); } + private static Metamodel.Type getOrFindType(Class type) { + System.out.println(type); + if (type == CompletableFuture.class) { + return getOrFindType(type.getTypeParameters()[0].getClass()); + } - @Nonnull - private static String getJavaDoc(NodeWithJavadoc typeDeclaration) { - if (typeDeclaration.getJavadoc().isPresent()) { - final var javadoc = typeDeclaration.getJavadoc().get(); - return javadoc.getDescription().toText() - + "\n\n" - + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) - .collect(Collectors.joining("\n")); + if (type == Unsafe.class || type == Class.class || type == Constructor.class || type == Proof.class) { + throw new IllegalStateException("Forbidden class reached!"); } - return ""; + + if (type == String.class) return Metamodel.BuiltinType.STRING; + if (type == Integer.class) return Metamodel.BuiltinType.INT; + if (type == Double.class) return Metamodel.BuiltinType.DOUBLE; + if (type == Long.class) return Metamodel.BuiltinType.LONG; + if (type == Character.class) return Metamodel.BuiltinType.LONG; + if (type == File.class) return Metamodel.BuiltinType.STRING; + if (type == Boolean.class) return Metamodel.BuiltinType.BOOL; + if (type == Boolean.TYPE) return Metamodel.BuiltinType.BOOL; + + if (type == Integer.TYPE) return Metamodel.BuiltinType.INT; + if (type == Double.TYPE) return Metamodel.BuiltinType.DOUBLE; + if (type == Long.TYPE) return Metamodel.BuiltinType.LONG; + if (type == Character.TYPE) return Metamodel.BuiltinType.LONG; + + System.out.println(type); + var t = types.stream().filter(it -> it.name().equals(type.getSimpleName())).findFirst(); + if (t.isPresent()) return t.get(); + var a = createType(type); + types.add(a); + return a; } - private static String type(MethodDeclaration method) { - if (method.getAnnotationByName("JsonNotification").isPresent()) - return "notification"; - if (method.getAnnotationByName("JsonRequest").isPresent()) - return "request"; - return ""; + private static Metamodel.Type createType(Class type) { + final var documentation = findDocumentation(type); + if (type.isEnum()) + return new Metamodel.EnumType(type.getSimpleName(), + Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), + documentation); + + + var obj = new Metamodel.ObjectType(type.getSimpleName(), new ArrayList<>(), documentation); + final var list = Arrays.stream(type.getDeclaredFields()) + .map(it -> new Metamodel.Field(it.getName(), getOrFindType(it.getType()).name())) + .toList(); + obj.fields().addAll(list); + return obj; } - private static boolean isExported(MethodDeclaration method) { - return method.getAnnotationByName("JsonNotification").isPresent() - || method.getAnnotationByName("JsonRequest").isPresent(); + private static String findDocumentation(Class type) { + var parser = initJavaParser(); + var fileName = findFileForType(type); + + if (Files.exists(fileName)) { + try { + return parser.parse(fileName).getResult().flatMap(CompilationUnit::getPrimaryType) + .flatMap(NodeWithJavadoc::getJavadocComment) + .map(Comment::getContent).orElse(""); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } else return ""; } - private static void printHeader(List> segments) { - out.format("# KeY-API%n%n"); + private static Path findFileForType(Class type) { + final var folderString = type.getPackageName().replaceAll("\\.", "/"); + var folder = Paths.get("keyext.api", "src", "main", "java", folderString); + final Class declaringClass = type.getDeclaringClass(); + var fileName = (declaringClass != null ? declaringClass : type).getSimpleName() + ".java"; + var file = folder.resolve(fileName); + return file; } - private static void printFooter(List> segments) { + private static void addClientEndpoint(Method method) { + var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); + var segment = jsonSegment.value(); + + var req = method.getAnnotation(JsonRequest.class); + var resp = method.getAnnotation(JsonNotification.class); + + var args = translate(method.getParameters()); + + if (req != null) { + var retType = getOrFindType(method.getGenericReturnType()); + Objects.requireNonNull(retType); + var mn = callMethodName(method.getName(), segment, req.value(), req.useSegment()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ClientRequest(mn, documentation, args, retType); + endpoints.add(mm); + return; + } + + if (resp != null) { + var mn = callMethodName(method.getName(), segment, resp.value(), resp.useSegment()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ClientNotification(mn, documentation, args); + endpoints.add(mm); + } + } + private static String callMethodName(String method, String segment, String userValue, boolean useSegment) { + if (!useSegment) { + if (userValue == null || userValue.isBlank()) { + return method; + } else { + return userValue; + } + } else { + if (userValue == null || userValue.isBlank()) { + return segment + "/" + method; + } else { + return segment + "/" + userValue; + } + } } + private static Metamodel.Type getOrFindType(Type genericReturnType) { + if (genericReturnType instanceof Class c) return getOrFindType(c); + if (genericReturnType instanceof ParameterizedType pt) { + if (Objects.equals(pt.getRawType().getTypeName(), CompletableFuture.class.getTypeName())) { + return getOrFindType(pt.getActualTypeArguments()[0]); + } + if (Objects.equals(pt.getRawType().getTypeName(), List.class.getTypeName())) { + var base = getOrFindType(pt.getActualTypeArguments()[0]); + return new Metamodel.ListType(base, ""); + } - private static boolean hasJsonSegment(TypeDeclaration it) { - return it.getAnnotationByName("JsonSegment").isPresent(); + if (Objects.equals(pt.getRawType().getTypeName(), Either.class.getTypeName())) { + var base1 = getOrFindType(pt.getActualTypeArguments()[0]); + var base2 = getOrFindType(pt.getActualTypeArguments()[1]); + return new Metamodel.EitherType(base1, base2, ""); + } + } + return null; } - private static String getJsonSegment(TypeDeclaration it) { - var ae = it.getAnnotationByName("JsonSegment").get(); - return ae.asSingleMemberAnnotationExpr().getMemberValue() - .asLiteralStringValueExpr().getValue(); + static JavaParser initJavaParser() { + ParserConfiguration config = new ParserConfiguration(); + config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); + config.setAttributeComments(true); + config.setLexicalPreservationEnabled(false); + config.setStoreTokens(false); + config.setIgnoreAnnotationsWhenAttributingComments(true); + config.setDoNotAssignCommentsPrecedingEmptyLines(true); + return new JavaParser(config); } + } diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/Metamodel.java new file mode 100644 index 00000000000..833699cfe0c --- /dev/null +++ b/keyext.api.doc/src/main/java/Metamodel.java @@ -0,0 +1,93 @@ +import org.jspecify.annotations.NullMarked; + +import java.util.List; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +@NullMarked +public class Metamodel { + public record KeyApi( + List endpoints, + List types + ) { + } + + sealed interface Endpoint { + String name(); + + String documentation(); + + default String kind() { + return getClass().getSimpleName(); + } + + List args(); + } + + public record Argument(String name, String type) { + } + + record ServerRequest(String name, String documentation, List args, Type returnType) implements Endpoint { + } + + record ServerNotification(String name, String documentation, List args) implements Endpoint { + } + + record ClientRequest(String name, String documentation, List args, Type returnType) implements Endpoint { + } + + record ClientNotification(String name, String documentation, List args) implements Endpoint { + } + + record Field(String name, /*Type*/ String type) { + } + + sealed interface Type { + default String kind() { + return getClass().getSimpleName(); + } + + String documentation(); + + String name(); + } + + enum BuiltinType implements Type { + INT, LONG, STRING, BOOL, DOUBLE; + + @Override + public String documentation() { + return "built-in data type"; + } + } + + record ListType(Type type, String documentation) implements Type { + @Override + public String name() { + return type().name() + "[]"; + } + } + + record ObjectType(String typeName, List fields, String documentation) implements Type { + @Override + public String name() { + return typeName; + } + } + + public record EitherType(Type a, Type b, String documentation) implements Type { + @Override + public String name() { + return "either"; + } + } + + public record EnumType(String typeName, List values, String documentation) implements Type { + @Override + public String name() { + return typeName; + } + } +} diff --git a/keyext.api.doc/src/main/java/PyGen.java b/keyext.api.doc/src/main/java/PyGen.java new file mode 100644 index 00000000000..357c2f51e8d --- /dev/null +++ b/keyext.api.doc/src/main/java/PyGen.java @@ -0,0 +1,136 @@ +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class PyGen implements Supplier { + private final Metamodel.KeyApi metamodel; + private PrintWriter out; + private final StringWriter target = new StringWriter(); + + public PyGen(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + + out.format(""" + import enum + import abc + import typing + from abc import abstractmethod + """); + + metamodel.types().forEach(this::printType); + server( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + + client( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + + } + return target.toString(); + } + + private void client(Stream sorted) { + out.format("class Client(abc.AbcMeta):%n"); + sorted.forEach(this::clientEndpoint); + } + + private void clientEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + out.format(" @abstractmethod%n"); + if (endpoint instanceof Metamodel.ClientRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, asPython(sr.returnType())); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + } + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" pass".formatted(endpoint.name(), "")); + out.println(); + out.println(); + } + + private void server(Stream sorted) { + out.format("class KeyServer():%n"); + sorted.forEach(this::serverEndpoint); + } + + private void serverEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + if (endpoint instanceof Metamodel.ServerRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, + asPython(sr.returnType())); + out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); + out.format(" return self.rpc.call_sync(\"%s\", %s)".formatted(endpoint.name(), "")); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" return self.rpc.call_async(\"%s\", %s)".formatted(endpoint.name(), "")); + } + out.println(); + out.println(); + } + + private void printType(Metamodel.Type type) { + if (type instanceof Metamodel.ObjectType ot) { + out.format("class %s:%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); + ot.fields().forEach(it -> out.format(" %s : %s%n".formatted(it.name(), asPython(it.type())))); + } else if (type instanceof Metamodel.EnumType et) { + out.format("class %s(enum.Enum):%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); + et.values().forEach(it -> out.format(" %s = None%n".formatted(it))); + } + out.println(); + } + + private String asPython(String typeName) { + return switch (typeName) { + case "INT" -> "int"; + case "LONG" -> "int"; + case "STRING" -> "str"; + case "BOOL" -> "bool"; + case "DOUBLE" -> "float"; + default -> { + var t = findType(typeName); + yield asPython(t); + } + }; + } + + private String asPython(Metamodel.Type t) { + if (t instanceof Metamodel.ListType lt) { + return "typing.List[" + asPython(lt.type()) + "]"; + } + + if (t instanceof Metamodel.EitherType lt) { + return "typing.Union[" + asPython(lt.a()) + ", " + asPython(lt.b()) + "]"; + } + return t.name(); + } + + private Metamodel.Type findType(String typeName) { + return this.metamodel.types().stream().filter(it -> it.name().equals(typeName)).findFirst() + .orElseThrow(() -> new RuntimeException("Could not find type: " + typeName)); + } +} \ No newline at end of file diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index c2b84249430..fbbbac93898 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -10,10 +10,10 @@ plugins { description "Verification server interface via JSON-RPC" dependencies { - implementation(project(":key.core")) - implementation(project(":key.ui")) + api(project(":key.core")) + api(project(":key.ui")) - implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") + api("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") implementation("org.eclipse.jetty.websocket:websocket-javax-server:10.0.16") diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index fd1b8352356..7ff86ae2c09 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -3,7 +3,6 @@ import de.uka.ilkd.key.control.AbstractUserInterfaceControl; import de.uka.ilkd.key.control.DefaultUserInterfaceControl; import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.gui.Example; import de.uka.ilkd.key.gui.ExampleChooser; import de.uka.ilkd.key.macros.ProofMacroFacade; import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; @@ -32,6 +31,7 @@ import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.internal.NodeText; +import org.keyproject.key.api.remoteapi.ExampleDesc; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteapi.PrintOptions; import org.keyproject.key.api.remoteclient.ClientApi; @@ -73,13 +73,14 @@ public KeyApiImpl() { @Override @JsonRequest - public CompletableFuture> examples() { - return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); + public CompletableFuture> examples() { + return CompletableFutures.computeAsync((c) -> + ExampleChooser.listExamples(ExampleChooser.lookForExamples()).stream().map(it -> ExampleDesc.from(it)).toList()); } @Override - public CompletableFuture shutdown() { - return CompletableFuture.completedFuture(null); + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(true); } @Override @@ -192,7 +193,8 @@ private List asNodeDesc(ProofId proofId, Stream nodes) { } private NodeDesc asNodeDesc(ProofId proofId, Node it) { - return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), it.getNodeInfo().getScriptRuleApplication()); + return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), + it.getNodeInfo().getScriptRuleApplication()); } @Override @@ -204,10 +206,11 @@ public CompletableFuture tree(ProofId proofId) { } private NodeDesc asNodeDescRecursive(ProofId proofId, Node root) { + final List list = root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList(); return new NodeDesc(new NodeId(proofId, root.serialNr()), root.getNodeInfo().getBranchLabel(), root.getNodeInfo().getScriptRuleApplication(), - root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList() + list ); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java deleted file mode 100644 index 0a27c633e5a..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api; - -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public record NodeTextDesc(NodeTextId id, String result) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java index a99bed5fda9..f28001e8c15 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java @@ -2,9 +2,3 @@ import org.keyproject.key.api.data.KeyIdentifications.NodeId; -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public record NodeTextId(NodeId nodeId, int nodeTextId) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java index 51e0053eed6..31714a361d7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -9,10 +9,11 @@ import de.uka.ilkd.key.pp.PosInSequent; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.*; -import org.checkerframework.checker.nullness.qual.NonNull; +import org.jspecify.annotations.NonNull; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; import org.keyproject.key.api.data.KeyIdentifications; +import org.keyproject.key.api.data.KeyIdentifications.NodeTextId; import org.keyproject.key.api.data.TermActionDesc; import org.keyproject.key.api.data.TermActionKind; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java index 0698a50a982..6d66823142a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java @@ -5,8 +5,7 @@ import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.keyproject.key.api.NodeTextId; +import org.jspecify.annotations.NonNull; import org.keyproject.key.api.internal.NodeText; import java.lang.ref.WeakReference; @@ -109,11 +108,12 @@ public record ProofId(EnvironmentId env, String proofId) { /** * @author Alexander Weigl - * @version 1 (13.10.23) + * @version 1 (29.10.23) */ - public record PrintId(String id) { + public record NodeTextId(NodeId nodeId, int nodeTextId) { } + /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java index 9e24e0f4cd7..eda5e693f64 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -1,6 +1,6 @@ package org.keyproject.key.api.data; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; import java.util.List; @@ -8,7 +8,8 @@ * @author Alexander Weigl * @version 1 (13.10.23) */ -public record NodeDesc(KeyIdentifications.NodeId nodeid, String branchLabel, +public record NodeDesc(KeyIdentifications.NodeId nodeid, + String branchLabel, boolean scriptRuleApplication, @Nullable List children ) { diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java new file mode 100644 index 00000000000..333b24f1c73 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.data; + + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record NodeTextDesc(KeyIdentifications.NodeTextId id, String result) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java index 4e2de0d4010..d952ea3a654 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java @@ -1,6 +1,7 @@ package org.keyproject.key.api.data; -import org.checkerframework.checker.nullness.qual.Nullable; + +import org.jspecify.annotations.Nullable; import java.util.List; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java deleted file mode 100644 index 96d22acee47..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java +++ /dev/null @@ -1,2 +0,0 @@ -package org.keyproject.key.api.data; - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java deleted file mode 100644 index 96d22acee47..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java +++ /dev/null @@ -1,2 +0,0 @@ -package org.keyproject.key.api.data; - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java index 9ccbb03049f..6c52dfd39aa 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java @@ -10,5 +10,5 @@ @JsonSegment("examples") public interface ExampleApi { @JsonRequest("list") - CompletableFuture> examples(); + CompletableFuture> examples(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java new file mode 100644 index 00000000000..c0091943899 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java @@ -0,0 +1,13 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.gui.Example; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record ExampleDesc(String name, String description) { + public static ExampleDesc from(Example example) { + return new ExampleDesc(example.getName(), example.getDescription()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java index 2f34293f0d5..959ed91570c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -3,8 +3,7 @@ import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.NodeTextDesc; -import org.keyproject.key.api.NodeTextId; +import org.keyproject.key.api.data.NodeTextDesc; import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java index ddd1fe408e6..00e85b9e021 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java @@ -29,7 +29,7 @@ public interface ServerManagement { * error: code and message set in case an exception happens during shutdown request. */ @JsonRequest - CompletableFuture shutdown(); + CompletableFuture shutdown(); /** * Exit Notification (:arrow_right:) diff --git a/keyext.api/src/main/python/keyapi/rpc.py b/keyext.api/src/main/python/keyapi/rpc.py deleted file mode 100644 index 89dc6f3e041..00000000000 --- a/keyext.api/src/main/python/keyapi/rpc.py +++ /dev/null @@ -1,76 +0,0 @@ -import abc -import json -from abc import abstractmethod -from multiprocessing import Process, SimpleQueue, Lock, Value - - -class Client(abc.ABC): - @abstractmethod - def handle(self, response): - pass - - -class JsonRPCHandler: - client: Client - - def __init__(self, in_stream, out_stream): - self.input = in_stream - self.out = out_stream - self.__id = 0 - self.client: Client - - self._events = dict() - self._responses = dict() - - # t: Process = Process(target=self.__read) - # t.start() - - def read_message(self): - length = 0 - for clength in self.input.readlines(): - if clength.startswith("Content-Length:"): - length = int(clength[14:]) - break - - payload = self.input.read(2 + length) - r = json.loads(payload) - if "id" in r: # JSON response for request - rid = r["id"] - # self._responses[rid] = r - # if rid in self._events: - # self._events[rid].set() - else: # JSON notification - self.client.handle(r) - return r - - def __read(self): - while True: - self.read_message() - - # def __create_event(self, number): - # self._events[number] = Event() - - def _send(self, method, params): - self.__id += 1 - id = self.__id - # self.__create_event(self.__id) - req = {"jsonrpc": "2.0", "method": method, "params": params, "id": self.__id} - - self._write(json.dumps(req)) - # self._wait_for(self.__id) - - r = dict() - while "id" in r and str(r[id]) != str(id): - r = self.read_message() - return r - - def _write(self, msg): - length = len(msg) - self.out.write(f"Content-Length: {length}\r\n") - self.out.write("\r\n") - self.out.write(msg) - self.out.write("\r\n") - self.out.flush() - - # def _wait_for(self, rid): - # self._events[rid].wait() diff --git a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index ae34b339231..5e0c87e06f5 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.keyproject.key.api.adapters.KeyAdapter; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; @@ -16,7 +15,6 @@ import java.util.Collections; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,7 +32,7 @@ void setup() throws IOException { inClient.connect(outServer); outClient.connect(inServer); - KeyApiImpl impl = new KeyApiImpl(new KeyAdapter(null)); + KeyApiImpl impl = new KeyApiImpl(); Launcher serverLauncher = StartServer.launch(outServer, inServer, impl); impl.setClientApi(serverLauncher.getRemoteProxy()); @@ -58,7 +56,7 @@ void setup() throws IOException { } @AfterEach - void teardown() throws ExecutionException, InterruptedException, TimeoutException { + void teardown() { serverListening.cancel(true); clientListening.cancel(true); } diff --git a/keyext.api/src/main/python/keyapi/__init__.py b/keyext.client.python/keyapi/__init__.py similarity index 54% rename from keyext.api/src/main/python/keyapi/__init__.py rename to keyext.client.python/keyapi/__init__.py index 8523f3801f5..4a913b39b2e 100644 --- a/keyext.api/src/main/python/keyapi/__init__.py +++ b/keyext.client.python/keyapi/__init__.py @@ -1,13 +1,4 @@ -from keyapi.rpc import JsonRPCHandler, Client - - -class KeyClient(Client): - def __int__(self): - pass - - def handle(self, res): - print(res) - +from keyapi.rpc import * class KeyStub(JsonRPCHandler): def __init__(self, input, output): diff --git a/keyext.client.python/keyapi/rpc.py b/keyext.client.python/keyapi/rpc.py new file mode 100644 index 00000000000..02ba2be474b --- /dev/null +++ b/keyext.client.python/keyapi/rpc.py @@ -0,0 +1,200 @@ +import enum +import json +import sys +import threading +from io import TextIOWrapper +from typing import Dict + +JSON_RPC_REQ_FORMAT = "Content-Length: {json_string_len}\r\n\r\n{json_string}" +LEN_HEADER = "Content-Length: " +TYPE_HEADER = "Content-Type: " + + +class MyEncoder(json.JSONEncoder): + """ + Encodes an object in JSON + """ + + def default(self, o): # pylint: disable=E0202 + return o.__dict__ + + +class ResponseError(Exception): + def __init__(self, error_code, message): + super().__init__(message) + self.error_code = error_code + + +class ErrorCodes(enum.Enum): + ParseError = 1 + + +class JsonRpcEndpoint(object): + ''' + Thread safe JSON RPC endpoint implementation. Responsible to recieve and send JSON RPC messages, as described in the + protocol. More information can be found: https://www.jsonrpc.org/ + ''' + + def __init__(self, stdin, stdout): + self.stdin = stdin + self.stdout = stdout + self.read_lock = threading.Lock() + self.write_lock = threading.Lock() + + @staticmethod + def __add_header(json_string): + ''' + Adds a header for the given json string + + :param str json_string: The string + :return: the string with the header + ''' + return JSON_RPC_REQ_FORMAT.format(json_string_len=len(json_string), json_string=json_string) + + def send_request(self, message): + ''' + Sends the given message. + + :param dict message: The message to send. + ''' + json_string = json.dumps(message, cls=MyEncoder) + jsonrpc_req = self.__add_header(json_string) + with self.write_lock: + self.stdin.write(jsonrpc_req.encode()) + self.stdin.flush() + + def recv_response(self): + ''' + Recives a message. + + :return: a message + ''' + with self.read_lock: + message_size = None + while True: + # read header + line = self.stdout.readline() + if not line: + # server quit + return None + line = line.decode("utf-8") + if not line.endswith("\r\n"): + raise ResponseError(ErrorCodes.ParseError, "Bad header: missing newline") + # remove the "\r\n" + line = line[:-2] + if line == "": + # done with the headers + break + elif line.startswith(LEN_HEADER): + line = line[len(LEN_HEADER):] + if not line.isdigit(): + raise ResponseError(ErrorCodes.ParseError, + "Bad header: size is not int") + message_size = int(line) + elif line.startswith(TYPE_HEADER): + # nothing todo with type for now. + pass + else: + raise ResponseError(ErrorCodes.ParseError, "Bad header: unkown header") + if not message_size: + raise ResponseError(ErrorCodes.ParseError, "Bad header: missing size") + + jsonrpc_res = self.stdout.read(message_size).decode("utf-8") + return json.loads(jsonrpc_res) + + +class LspEndpoint(threading.Thread): + def __init__(self, json_rpc_endpoint: JsonRpcEndpoint, method_callbacks=None, notify_callbacks=None, timeout=2): + super().__init__() + self.json_rpc_endpoint: JsonRpcEndpoint = json_rpc_endpoint + self.notify_callbacks: Dict = notify_callbacks or {} + self.method_callbacks: Dict = method_callbacks or {} + self.event_dict = {} + self.response_dict = {} + self.next_id = 0 + self._timeout = timeout + self.shutdown_flag = False + + def handle_result(self, rpc_id, result, error): + self.response_dict[rpc_id] = (result, error) + cond = self.event_dict[rpc_id] + cond.acquire() + cond.notify() + cond.release() + + def stop(self): + self.shutdown_flag = True + + def run(self): + while not self.shutdown_flag: + try: + jsonrpc_message = self.json_rpc_endpoint.recv_response() + if jsonrpc_message is None: + print("server quit") + break + method = jsonrpc_message.get("method") + result = jsonrpc_message.get("result") + error = jsonrpc_message.get("error") + rpc_id = jsonrpc_message.get("id") + params = jsonrpc_message.get("params") + + if method: + if rpc_id: + # a call for method + if method not in self.method_callbacks: + raise ResponseError(ErrorCodes.MethodNotFound, + "Method not found: {method}".format(method=method)) + result = self.method_callbacks[method](params) + self.send_response(rpc_id, result, None) + else: + # a call for notify + if method not in self.notify_callbacks: + # Have nothing to do with this. + print("Notify method not found: {method}.".format(method=method)) + else: + self.notify_callbacks[method](params) + else: + self.handle_result(rpc_id, result, error) + except ResponseError as e: + self.send_response(rpc_id, None, e) + + def send_response(self, id, result, error): + message_dict = {"jsonrpc": "2.0", "id": id} + if result: + message_dict["result"] = result + if error: + message_dict["error"] = error + self.json_rpc_endpoint.send_request(message_dict) + + def send_message(self, method_name, params, id=None): + message_dict = {} + message_dict["jsonrpc"] = "2.0" + if id is not None: + message_dict["id"] = id + message_dict["method"] = method_name + message_dict["params"] = params + self.json_rpc_endpoint.send_request(message_dict) + + def call_method(self, method_name, **kwargs): + current_id = self.next_id + self.next_id += 1 + cond = threading.Condition() + self.event_dict[current_id] = cond + + cond.acquire() + self.send_message(method_name, kwargs, current_id) + if self.shutdown_flag: + return None + + if not cond.wait(timeout=self._timeout): + raise TimeoutError() + cond.release() + + self.event_dict.pop(current_id) + result, error = self.response_dict.pop(current_id) + if error: + raise ResponseError(error.get("code"), error.get("message"), error.get("data")) + return result + + def send_notification(self, method_name, **kwargs): + self.send_message(method_name, kwargs) diff --git a/keyext.api/src/main/python/main.py b/keyext.client.python/main.py similarity index 100% rename from keyext.api/src/main/python/main.py rename to keyext.client.python/main.py diff --git a/keyext.client.python/rwtest.py b/keyext.client.python/rwtest.py new file mode 100644 index 00000000000..312532192dc --- /dev/null +++ b/keyext.client.python/rwtest.py @@ -0,0 +1,402 @@ +import enum +import abc +import typing +from abc import abstractmethod + + +class ExampleDesc: + """""" + + name: str + description: str + + +class ProofScriptCommandDesc: + """""" + + +class ProofMacroDesc: + """""" + + name: str + category: str + description: str + scriptCommandName: str + + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + + +class SetTraceParams: + """""" + + value: TraceValue + + +class EnvironmentId: + """""" + + envId: str + + +class ProofId: + """""" + + env: EnvironmentId + proofId: str + + +class TreeNodeDesc: + """""" + + +class TreeNodeId: + """""" + + id: str + + +class NodeId: + """""" + + proofId: ProofId + nodeId: int + + +class PrintOptions: + """""" + + unicode: bool + width: int + indentation: int + pure: bool + termLabels: bool + + +class NodeTextId: + """""" + + nodeId: NodeId + nodeTextId: int + + +class NodeTextDesc: + """""" + + id: NodeTextId + result: str + + +class TermActionId: + """""" + + nodeId: NodeId + pio: str + id: str + + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + + +class TermActionDesc: + """""" + + commandId: TermActionId + displayName: str + description: str + category: str + kind: TermActionKind + + +class List: + """""" + + +class SortDesc: + """""" + + string: str + documentation: str + extendsSorts: List + anAbstract: bool + s: str + + +class FunctionDesc: + """""" + + name: str + sort: str + retSort: SortDesc + argSorts: List + rigid: bool + unique: bool + skolemConstant: bool + + +class ContractId: + """""" + + envId: EnvironmentId + contractId: int + + +class ContractDesc: + """""" + + contractId: ContractId + name: str + displayName: str + typeName: str + htmlText: str + plainText: str + + +class LoadParams: + """""" + + keyFile: str + javaFile: str + classPath: List + bootClassPath: str + includes: List + + +class ProblemDefinition: + """""" + + sorts: List + functions: List + predicates: List + antecTerms: List + succTerms: List + + +class LogTraceParams: + """""" + + messag: str + verbose: str + + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + + +class ShowMessageParams: + """""" + + type: MessageType + message: str + + + +class ShowMessageRequestParams: + """""" + + type: MessageType + message: str + actions: typing.List[MessageActionItem] + + +class MessageActionItem: + """""" + + title: str + + +class Range: + """""" + + start: int + end: int + + +class ShowDocumentParams: + """""" + + uri: str + external: bool + takeFocus: bool + selection: Range + + +class ShowDocumentResult: + """""" + + success: bool + + +class TaskFinishedInfo: + """""" + + +class TaskStartedInfo: + """""" + + +class KeyServer(): + def env_contracts(self, arg0: EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self.rpc.call_sync("env/contracts", ) + + def env_functions(self, arg0: EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self.rpc.call_sync("env/functions", ) + + def env_openContract(self, arg0: ContractId) -> ProofId: + """""" + + return self.rpc.call_sync("env/openContract", ) + + def env_sorts(self, arg0: EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self.rpc.call_sync("env/sorts", ) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self.rpc.call_sync("examples/list", ) + + def goal_actions(self, arg0: NodeTextId, arg1: int) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/actions", ) + + def goal_apply_action(self, arg0: TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/apply_action", ) + + def goal_free(self, arg0: NodeTextId): + """""" + + return self.rpc.call_async("goal/free", ) + + def goal_print(self, arg0: NodeId, arg1: PrintOptions) -> NodeTextDesc: + """""" + + return self.rpc.call_sync("goal/print", ) + + def loading_load(self, arg0: LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self.rpc.call_sync("loading/load", ) + + def loading_loadExample(self, arg0: str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadExample", ) + + def loading_loadKey(self, arg0: str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadKey", ) + + def loading_loadProblem(self, arg0: ProblemDefinition) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadProblem", ) + + def loading_loadTerm(self, arg0: str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadTerm", ) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self.rpc.call_sync("meta/available_macros", ) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self.rpc.call_sync("meta/available_script_commands", ) + + def meta_version(self, ) -> str: + """""" + + return self.rpc.call_sync("meta/version", ) + + def proofTree_children(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/children", ) + + def proofTree_root(self, arg0: ProofId) -> TreeNodeDesc: + """""" + + return self.rpc.call_sync("proofTree/root", ) + + def proofTree_subtree(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/subtree", ) + + def server_exit(self, ): + """""" + + return self.rpc.call_async("server/exit", ) + + def server_setTrace(self, arg0: SetTraceParams): + """""" + + return self.rpc.call_async("server/setTrace", ) + + def server_shutdown(self, ) -> bool: + """""" + + return self.rpc.call_sync("server/shutdown", ) + + +class Client(abc.ABCMeta): + @abstractmethod + def client_logTrace(self, arg0: LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, arg0: str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, arg0: ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, arg0: ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, arg0: ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass From c7000129b0190dbcaa4c388ed6b91b38cd12f095 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Wed, 1 Nov 2023 15:52:40 +0100 Subject: [PATCH 07/50] running for primitive data types, somethings wrong in de-/serialization --- api.meta.json | 445 +++++++++------ api.meta.md | 53 +- api.py | 374 ------------ keydata.py | 493 ++++++++++++++++ .../src/main/java/ExtractMetaData.java | 25 +- keyext.api.doc/src/main/java/Metamodel.java | 7 +- keyext.api.doc/src/main/java/PyGen.java | 136 ----- .../src/main/java/PythionGenerator.java | 223 ++++++++ keyext.api/build.gradle | 1 + .../keyproject/key/api/GenericSerializer.java | 56 ++ .../org/keyproject/key/api/KeyApiImpl.java | 3 +- .../org/keyproject/key/api/StartServer.java | 7 +- .../key/api/adapters/KeyAdapter.java | 2 +- .../ShowMessageRequestParams.java | 4 +- keyext.client.python/keyapi/__init__.py | 12 +- keyext.client.python/keyapi/keydata.py | 533 ++++++++++++++++++ keyext.client.python/keyapi/rpc.py | 58 +- keyext.client.python/keyapi/server.py | 161 ++++++ keyext.client.python/main.py | 22 +- keyext.client.python/rwtest.py | 402 ------------- server.py | 159 ++++++ 21 files changed, 2023 insertions(+), 1153 deletions(-) delete mode 100644 api.py create mode 100644 keydata.py delete mode 100644 keyext.api.doc/src/main/java/PyGen.java create mode 100644 keyext.api.doc/src/main/java/PythionGenerator.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java create mode 100644 keyext.client.python/keyapi/keydata.py create mode 100644 keyext.client.python/keyapi/server.py delete mode 100644 keyext.client.python/rwtest.py create mode 100644 server.py diff --git a/api.meta.json b/api.meta.json index 180b16a3019..953b76c6088 100644 --- a/api.meta.json +++ b/api.meta.json @@ -10,11 +10,13 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -51,19 +53,23 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "scriptCommandName", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -87,7 +93,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "SetTraceParams" } ] @@ -97,7 +103,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "ProofId" } ], @@ -112,11 +118,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "proof", "type": "ProofId" }, { - "name": "arg1", + "name": "nodeId", "type": "TreeNodeId" } ], @@ -134,11 +140,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "proof", "type": "ProofId" }, { - "name": "arg1", + "name": "nodeId", "type": "TreeNodeId" } ], @@ -156,11 +162,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "NodeId" }, { - "name": "arg1", + "name": "options", "type": "PrintOptions" } ], @@ -169,11 +175,13 @@ "fields": [ { "name": "id", - "type": "NodeTextId" + "type": "NodeTextId", + "documentation": "" }, { "name": "result", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -184,11 +192,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "NodeTextId" }, { - "name": "arg1", + "name": "pos", "type": "INT" } ], @@ -198,23 +206,28 @@ "fields": [ { "name": "commandId", - "type": "TermActionId" + "type": "TermActionId", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "kind", - "type": "TermActionKind" + "type": "TermActionKind", + "documentation": "" } ], "documentation": "" @@ -227,7 +240,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "TermActionId" } ], @@ -237,23 +250,28 @@ "fields": [ { "name": "commandId", - "type": "TermActionId" + "type": "TermActionId", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "kind", - "type": "TermActionKind" + "type": "TermActionKind", + "documentation": "" } ], "documentation": "" @@ -266,7 +284,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "NodeTextId" } ] @@ -276,7 +294,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "env", "type": "EnvironmentId" } ], @@ -286,31 +304,38 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "sort", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "retSort", - "type": "SortDesc" + "type": "SortDesc", + "documentation": "" }, { "name": "argSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "rigid", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "unique", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "skolemConstant", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -323,7 +348,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "env", "type": "EnvironmentId" } ], @@ -333,23 +358,28 @@ "fields": [ { "name": "string", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "documentation", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "extendsSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "anAbstract", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "s", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -362,7 +392,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "env", "type": "EnvironmentId" } ], @@ -372,27 +402,33 @@ "fields": [ { "name": "contractId", - "type": "ContractId" + "type": "ContractId", + "documentation": "" }, { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "typeName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "htmlText", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "plainText", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -405,7 +441,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "contractId", "type": "ContractId" } ], @@ -414,11 +450,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -429,7 +467,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "LoadParams" } ], @@ -439,7 +477,8 @@ "fields": [ { "name": "envId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -449,11 +488,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -462,11 +503,11 @@ } }, { - "name": "loading/loadKey", + "name": "loading/loadExample", "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "STRING" } ], @@ -475,23 +516,25 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" } }, { - "name": "loading/loadExample", + "name": "loading/loadProblem", "documentation": "", "args": [ { - "name": "arg0", - "type": "STRING" + "name": "problem", + "type": "ProblemDefinition" } ], "returnType": { @@ -499,23 +542,25 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" } }, { - "name": "loading/loadProblem", + "name": "loading/loadKey", "documentation": "", "args": [ { - "name": "arg0", - "type": "ProblemDefinition" + "name": "content", + "type": "STRING" } ], "returnType": { @@ -523,11 +568,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -538,7 +585,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "term", "type": "STRING" } ], @@ -547,11 +594,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -562,7 +611,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "e", "type": "STRING" } ] @@ -572,7 +621,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "LogTraceParams" } ] @@ -582,7 +631,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "ShowMessageParams" } ] @@ -592,7 +641,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "ShowMessageRequestParams" } ], @@ -601,7 +650,8 @@ "fields": [ { "name": "title", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -612,7 +662,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "ShowDocumentParams" } ], @@ -621,7 +671,8 @@ "fields": [ { "name": "success", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -634,11 +685,13 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -653,19 +706,23 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "scriptCommandName", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -684,7 +741,8 @@ "fields": [ { "name": "value", - "type": "TraceValue" + "type": "TraceValue", + "documentation": "" } ], "documentation": "" @@ -694,7 +752,8 @@ "fields": [ { "name": "envId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -704,11 +763,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -723,7 +784,8 @@ "fields": [ { "name": "id", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -733,11 +795,13 @@ "fields": [ { "name": "proofId", - "type": "ProofId" + "type": "ProofId", + "documentation": "" }, { "name": "nodeId", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -747,23 +811,28 @@ "fields": [ { "name": "unicode", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "width", - "type": "INT" + "type": "INT", + "documentation": "" }, { "name": "indentation", - "type": "INT" + "type": "INT", + "documentation": "" }, { "name": "pure", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "termLabels", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -773,11 +842,13 @@ "fields": [ { "name": "nodeId", - "type": "NodeId" + "type": "NodeId", + "documentation": "" }, { "name": "nodeTextId", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -787,11 +858,13 @@ "fields": [ { "name": "id", - "type": "NodeTextId" + "type": "NodeTextId", + "documentation": "" }, { "name": "result", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -801,15 +874,18 @@ "fields": [ { "name": "nodeId", - "type": "NodeId" + "type": "NodeId", + "documentation": "" }, { "name": "pio", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "id", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -829,23 +905,28 @@ "fields": [ { "name": "commandId", - "type": "TermActionId" + "type": "TermActionId", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "kind", - "type": "TermActionKind" + "type": "TermActionKind", + "documentation": "" } ], "documentation": "" @@ -860,23 +941,28 @@ "fields": [ { "name": "string", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "documentation", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "extendsSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "anAbstract", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "s", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -886,31 +972,38 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "sort", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "retSort", - "type": "SortDesc" + "type": "SortDesc", + "documentation": "" }, { "name": "argSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "rigid", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "unique", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "skolemConstant", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -920,11 +1013,13 @@ "fields": [ { "name": "envId", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "contractId", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -934,27 +1029,33 @@ "fields": [ { "name": "contractId", - "type": "ContractId" + "type": "ContractId", + "documentation": "" }, { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "typeName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "htmlText", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "plainText", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -964,23 +1065,28 @@ "fields": [ { "name": "keyFile", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "javaFile", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "classPath", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "bootClassPath", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "includes", - "type": "List" + "type": "List", + "documentation": "" } ], "documentation": "" @@ -990,23 +1096,28 @@ "fields": [ { "name": "sorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "functions", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "predicates", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "antecTerms", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "succTerms", - "type": "List" + "type": "List", + "documentation": "" } ], "documentation": "" @@ -1016,11 +1127,13 @@ "fields": [ { "name": "messag", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "verbose", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -1042,34 +1155,34 @@ "fields": [ { "name": "type", - "type": "MessageType" + "type": "MessageType", + "documentation": "" }, { "name": "message", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" }, - { - "typeName": "MessageActionItem[]", - "fields": [], - "documentation": "" - }, { "typeName": "ShowMessageRequestParams", "fields": [ { "name": "type", - "type": "MessageType" + "type": "MessageType", + "documentation": "" }, { "name": "message", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "actions", - "type": "MessageActionItem[]" + "type": "List", + "documentation": "" } ], "documentation": "" @@ -1079,7 +1192,8 @@ "fields": [ { "name": "title", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -1089,11 +1203,13 @@ "fields": [ { "name": "start", - "type": "INT" + "type": "INT", + "documentation": "" }, { "name": "end", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -1103,19 +1219,23 @@ "fields": [ { "name": "uri", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "external", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "takeFocus", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "selection", - "type": "Range" + "type": "Range", + "documentation": "" } ], "documentation": "" @@ -1125,7 +1245,8 @@ "fields": [ { "name": "success", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" diff --git a/api.meta.md b/api.meta.md index f53d88619f3..f6d7a29c764 100644 --- a/api.meta.md +++ b/api.meta.md @@ -80,13 +80,6 @@ type MessageActionItem { } ``` -### Type: MessageActionItem[] -``` -type MessageActionItem[] { - -} -``` - ### Type: MessageType ``` enum MessageType { Unused, Error, Warning, Info, Log, Debug } @@ -206,7 +199,7 @@ type ShowMessageParams { ### Type: ShowMessageRequestParams ``` type ShowMessageRequestParams { - actions : MessageActionItem[] + actions : List message : STRING type : MessageType } @@ -285,63 +278,63 @@ type TreeNodeId { ### client/logTrace (`server ~~> client`) ``` -Client.client/logTrace( arg0 : LogTraceParams ) **async** +Client.client/logTrace( params : LogTraceParams ) **async** ``` ### client/sayHello (`server ~~> client`) ``` -Client.client/sayHello( arg0 : STRING ) **async** +Client.client/sayHello( e : STRING ) **async** ``` ### client/showDocument (`server -> client`) ``` -Client.client/showDocument( arg0 : ShowDocumentParams ) -> ShowDocumentResult +Client.client/showDocument( params : ShowDocumentParams ) -> ShowDocumentResult ``` ### client/sm (`server ~~> client`) ``` -Client.client/sm( arg0 : ShowMessageParams ) **async** +Client.client/sm( params : ShowMessageParams ) **async** ``` ### client/userResponse (`server -> client`) ``` -Client.client/userResponse( arg0 : ShowMessageRequestParams ) -> MessageActionItem +Client.client/userResponse( params : ShowMessageRequestParams ) -> MessageActionItem ``` ### env/contracts (`client -> server`) ``` -Server.env/contracts( arg0 : EnvironmentId ) -> ContractDesc[] +Server.env/contracts( env : EnvironmentId ) -> ContractDesc[] ``` ### env/functions (`client -> server`) ``` -Server.env/functions( arg0 : EnvironmentId ) -> FunctionDesc[] +Server.env/functions( env : EnvironmentId ) -> FunctionDesc[] ``` ### env/openContract (`client -> server`) ``` -Server.env/openContract( arg0 : ContractId ) -> ProofId +Server.env/openContract( contractId : ContractId ) -> ProofId ``` ### env/sorts (`client -> server`) ``` -Server.env/sorts( arg0 : EnvironmentId ) -> SortDesc[] +Server.env/sorts( env : EnvironmentId ) -> SortDesc[] ``` @@ -355,63 +348,63 @@ Server.examples/list( ) -> ExampleDesc[] ### goal/actions (`client -> server`) ``` -Server.goal/actions( arg0 : NodeTextId, arg1 : INT ) -> TermActionDesc[] +Server.goal/actions( id : NodeTextId, pos : INT ) -> TermActionDesc[] ``` ### goal/apply_action (`client -> server`) ``` -Server.goal/apply_action( arg0 : TermActionId ) -> TermActionDesc[] +Server.goal/apply_action( id : TermActionId ) -> TermActionDesc[] ``` ### goal/free (`client ~~> server`) ``` -Server.goal/free( arg0 : NodeTextId ) **async** +Server.goal/free( id : NodeTextId ) **async** ``` ### goal/print (`client -> server`) ``` -Server.goal/print( arg0 : NodeId, arg1 : PrintOptions ) -> NodeTextDesc +Server.goal/print( id : NodeId, options : PrintOptions ) -> NodeTextDesc ``` ### loading/load (`client -> server`) ``` -Server.loading/load( arg0 : LoadParams ) -> either +Server.loading/load( params : LoadParams ) -> either ``` ### loading/loadExample (`client -> server`) ``` -Server.loading/loadExample( arg0 : STRING ) -> ProofId +Server.loading/loadExample( id : STRING ) -> ProofId ``` ### loading/loadKey (`client -> server`) ``` -Server.loading/loadKey( arg0 : STRING ) -> ProofId +Server.loading/loadKey( content : STRING ) -> ProofId ``` ### loading/loadProblem (`client -> server`) ``` -Server.loading/loadProblem( arg0 : ProblemDefinition ) -> ProofId +Server.loading/loadProblem( problem : ProblemDefinition ) -> ProofId ``` ### loading/loadTerm (`client -> server`) ``` -Server.loading/loadTerm( arg0 : STRING ) -> ProofId +Server.loading/loadTerm( term : STRING ) -> ProofId ``` @@ -439,21 +432,21 @@ Server.meta/version( ) -> STRING ### proofTree/children (`client -> server`) ``` -Server.proofTree/children( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +Server.proofTree/children( proof : ProofId, nodeId : TreeNodeId ) -> TreeNodeDesc[] ``` ### proofTree/root (`client -> server`) ``` -Server.proofTree/root( arg0 : ProofId ) -> TreeNodeDesc +Server.proofTree/root( id : ProofId ) -> TreeNodeDesc ``` ### proofTree/subtree (`client -> server`) ``` -Server.proofTree/subtree( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +Server.proofTree/subtree( proof : ProofId, nodeId : TreeNodeId ) -> TreeNodeDesc[] ``` @@ -467,7 +460,7 @@ Server.server/exit( ) **async** ### server/setTrace (`client ~~> server`) ``` -Server.server/setTrace( arg0 : SetTraceParams ) **async** +Server.server/setTrace( params : SetTraceParams ) **async** ``` diff --git a/api.py b/api.py deleted file mode 100644 index c83050a763e..00000000000 --- a/api.py +++ /dev/null @@ -1,374 +0,0 @@ -import enum -import abc -import typing -class ExampleDesc: - """""" - - name : str - description : str - -class ProofScriptCommandDesc: - """""" - - -class ProofMacroDesc: - """""" - - name : str - category : str - description : str - scriptCommandName : str - -class TraceValue(enum.Enum): - """""" - - Off = None - Message = None - All = None - -class SetTraceParams: - """""" - - value : TraceValue - -class EnvironmentId: - """""" - - envId : str - -class ProofId: - """""" - - env : EnvironmentId - proofId : str - -class TreeNodeDesc: - """""" - - -class TreeNodeId: - """""" - - id : str - -class NodeId: - """""" - - proofId : ProofId - nodeId : int - -class PrintOptions: - """""" - - unicode : bool - width : int - indentation : int - pure : bool - termLabels : bool - -class NodeTextId: - """""" - - nodeId : NodeId - nodeTextId : int - -class NodeTextDesc: - """""" - - id : NodeTextId - result : str - -class TermActionId: - """""" - - nodeId : NodeId - pio : str - id : str - -class TermActionKind(enum.Enum): - """""" - - BuiltIn = None - Script = None - Macro = None - Taclet = None - -class TermActionDesc: - """""" - - commandId : TermActionId - displayName : str - description : str - category : str - kind : TermActionKind - -class List: - """""" - - -class SortDesc: - """""" - - string : str - documentation : str - extendsSorts : List - anAbstract : bool - s : str - -class FunctionDesc: - """""" - - name : str - sort : str - retSort : SortDesc - argSorts : List - rigid : bool - unique : bool - skolemConstant : bool - -class ContractId: - """""" - - envId : EnvironmentId - contractId : int - -class ContractDesc: - """""" - - contractId : ContractId - name : str - displayName : str - typeName : str - htmlText : str - plainText : str - -class LoadParams: - """""" - - keyFile : str - javaFile : str - classPath : List - bootClassPath : str - includes : List - -class ProblemDefinition: - """""" - - sorts : List - functions : List - predicates : List - antecTerms : List - succTerms : List - -class LogTraceParams: - """""" - - messag : str - verbose : str - -class MessageType(enum.Enum): - """""" - - Unused = None - Error = None - Warning = None - Info = None - Log = None - Debug = None - -class ShowMessageParams: - """""" - - type : MessageType - message : str - -class MessageActionItem[]: - """""" - - -class ShowMessageRequestParams: - """""" - - type : MessageType - message : str - actions : MessageActionItem[] - -class MessageActionItem: - """""" - - title : str - -class Range: - """""" - - start : int - end : int - -class ShowDocumentParams: - """""" - - uri : str - external : bool - takeFocus : bool - selection : Range - -class ShowDocumentResult: - """""" - - success : bool - -class TaskFinishedInfo: - """""" - - -class TaskStartedInfo: - """""" - - -class KeyServer(): - def env_contracts(self, arg0 : EnvironmentId) -> typing.List[ContractDesc]: - """""" - - return self.rpc.call_sync("env/contracts", ) - - def env_functions(self, arg0 : EnvironmentId) -> typing.List[FunctionDesc]: - """""" - - return self.rpc.call_sync("env/functions", ) - - def env_openContract(self, arg0 : ContractId) -> ProofId: - """""" - - return self.rpc.call_sync("env/openContract", ) - - def env_sorts(self, arg0 : EnvironmentId) -> typing.List[SortDesc]: - """""" - - return self.rpc.call_sync("env/sorts", ) - - def examples_list(self, ) -> typing.List[ExampleDesc]: - """""" - - return self.rpc.call_sync("examples/list", ) - - def goal_actions(self, arg0 : NodeTextId, arg1 : int) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/actions", ) - - def goal_apply_action(self, arg0 : TermActionId) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/apply_action", ) - - def goal_free(self, arg0 : NodeTextId): - """""" - - return self.rpc.call_async("goal/free", ) - - def goal_print(self, arg0 : NodeId, arg1 : PrintOptions) -> NodeTextDesc: - """""" - - return self.rpc.call_sync("goal/print", ) - - def loading_load(self, arg0 : LoadParams) -> typing.Union[EnvironmentId, ProofId]: - """""" - - return self.rpc.call_sync("loading/load", ) - - def loading_loadExample(self, arg0 : str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadExample", ) - - def loading_loadKey(self, arg0 : str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadKey", ) - - def loading_loadProblem(self, arg0 : ProblemDefinition) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadProblem", ) - - def loading_loadTerm(self, arg0 : str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadTerm", ) - - def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: - """""" - - return self.rpc.call_sync("meta/available_macros", ) - - def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: - """""" - - return self.rpc.call_sync("meta/available_script_commands", ) - - def meta_version(self, ) -> STRING: - """""" - - return self.rpc.call_sync("meta/version", ) - - def proofTree_children(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/children", ) - - def proofTree_root(self, arg0 : ProofId) -> TreeNodeDesc: - """""" - - return self.rpc.call_sync("proofTree/root", ) - - def proofTree_subtree(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/subtree", ) - - def server_exit(self, ): - """""" - - return self.rpc.call_async("server/exit", ) - - def server_setTrace(self, arg0 : SetTraceParams): - """""" - - return self.rpc.call_async("server/setTrace", ) - - def server_shutdown(self, ) -> BOOL: - """""" - - return self.rpc.call_sync("server/shutdown", ) - -class Client(abc.AbcMeta): - @abstractmethod - def client_logTrace(self, arg0 : LogTraceParams): - """""" - - pass - - @abstractmethod - def client_sayHello(self, arg0 : str): - """""" - - pass - - @abstractmethod - def client_showDocument(self, arg0 : ShowDocumentParams) -> ShowDocumentResult: - """""" - - pass - - @abstractmethod - def client_sm(self, arg0 : ShowMessageParams): - """""" - - pass - - @abstractmethod - def client_userResponse(self, arg0 : ShowMessageRequestParams) -> MessageActionItem: - """""" - - pass - diff --git a/keydata.py b/keydata.py new file mode 100644 index 00000000000..59511c2a7a8 --- /dev/null +++ b/keydata.py @@ -0,0 +1,493 @@ +from __future__ import annotations +import enum +import abc +import typing +from abc import abstractmethod, ABCMeta + +class ExampleDesc: + """""" + + name : str + """""" + + description : str + """""" + + def __init__(self, name, description): + self.name = name + self.description = description + +class ProofScriptCommandDesc: + """""" + + def __init__(self, ): + pass + + +class ProofMacroDesc: + """""" + + name : str + """""" + + category : str + """""" + + description : str + """""" + + scriptCommandName : str + """""" + + def __init__(self, name, category, description, scriptCommandName): + self.name = name + self.category = category + self.description = description + self.scriptCommandName = scriptCommandName + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + +class SetTraceParams: + """""" + + value : TraceValue + """""" + + def __init__(self, value): + self.value = value + +class EnvironmentId: + """""" + + envId : str + """""" + + def __init__(self, envId): + self.envId = envId + +class ProofId: + """""" + + env : EnvironmentId + """""" + + proofId : str + """""" + + def __init__(self, env, proofId): + self.env = env + self.proofId = proofId + +class TreeNodeDesc: + """""" + + def __init__(self, ): + pass + + +class TreeNodeId: + """""" + + id : str + """""" + + def __init__(self, id): + self.id = id + +class NodeId: + """""" + + proofId : ProofId + """""" + + nodeId : int + """""" + + def __init__(self, proofId, nodeId): + self.proofId = proofId + self.nodeId = nodeId + +class PrintOptions: + """""" + + unicode : bool + """""" + + width : int + """""" + + indentation : int + """""" + + pure : bool + """""" + + termLabels : bool + """""" + + def __init__(self, unicode, width, indentation, pure, termLabels): + self.unicode = unicode + self.width = width + self.indentation = indentation + self.pure = pure + self.termLabels = termLabels + +class NodeTextId: + """""" + + nodeId : NodeId + """""" + + nodeTextId : int + """""" + + def __init__(self, nodeId, nodeTextId): + self.nodeId = nodeId + self.nodeTextId = nodeTextId + +class NodeTextDesc: + """""" + + id : NodeTextId + """""" + + result : str + """""" + + def __init__(self, id, result): + self.id = id + self.result = result + +class TermActionId: + """""" + + nodeId : NodeId + """""" + + pio : str + """""" + + id : str + """""" + + def __init__(self, nodeId, pio, id): + self.nodeId = nodeId + self.pio = pio + self.id = id + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + +class TermActionDesc: + """""" + + commandId : TermActionId + """""" + + displayName : str + """""" + + description : str + """""" + + category : str + """""" + + kind : TermActionKind + """""" + + def __init__(self, commandId, displayName, description, category, kind): + self.commandId = commandId + self.displayName = displayName + self.description = description + self.category = category + self.kind = kind + +class List: + """""" + + def __init__(self, ): + pass + + +class SortDesc: + """""" + + string : str + """""" + + documentation : str + """""" + + extendsSorts : List + """""" + + anAbstract : bool + """""" + + s : str + """""" + + def __init__(self, string, documentation, extendsSorts, anAbstract, s): + self.string = string + self.documentation = documentation + self.extendsSorts = extendsSorts + self.anAbstract = anAbstract + self.s = s + +class FunctionDesc: + """""" + + name : str + """""" + + sort : str + """""" + + retSort : SortDesc + """""" + + argSorts : List + """""" + + rigid : bool + """""" + + unique : bool + """""" + + skolemConstant : bool + """""" + + def __init__(self, name, sort, retSort, argSorts, rigid, unique, skolemConstant): + self.name = name + self.sort = sort + self.retSort = retSort + self.argSorts = argSorts + self.rigid = rigid + self.unique = unique + self.skolemConstant = skolemConstant + +class ContractId: + """""" + + envId : EnvironmentId + """""" + + contractId : int + """""" + + def __init__(self, envId, contractId): + self.envId = envId + self.contractId = contractId + +class ContractDesc: + """""" + + contractId : ContractId + """""" + + name : str + """""" + + displayName : str + """""" + + typeName : str + """""" + + htmlText : str + """""" + + plainText : str + """""" + + def __init__(self, contractId, name, displayName, typeName, htmlText, plainText): + self.contractId = contractId + self.name = name + self.displayName = displayName + self.typeName = typeName + self.htmlText = htmlText + self.plainText = plainText + +class LoadParams: + """""" + + keyFile : str + """""" + + javaFile : str + """""" + + classPath : List + """""" + + bootClassPath : str + """""" + + includes : List + """""" + + def __init__(self, keyFile, javaFile, classPath, bootClassPath, includes): + self.keyFile = keyFile + self.javaFile = javaFile + self.classPath = classPath + self.bootClassPath = bootClassPath + self.includes = includes + +class ProblemDefinition: + """""" + + sorts : List + """""" + + functions : List + """""" + + predicates : List + """""" + + antecTerms : List + """""" + + succTerms : List + """""" + + def __init__(self, sorts, functions, predicates, antecTerms, succTerms): + self.sorts = sorts + self.functions = functions + self.predicates = predicates + self.antecTerms = antecTerms + self.succTerms = succTerms + +class LogTraceParams: + """""" + + messag : str + """""" + + verbose : str + """""" + + def __init__(self, messag, verbose): + self.messag = messag + self.verbose = verbose + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + +class ShowMessageParams: + """""" + + type : MessageType + """""" + + message : str + """""" + + def __init__(self, type, message): + self.type = type + self.message = message + +class ShowMessageRequestParams: + """""" + + type : MessageType + """""" + + message : str + """""" + + actions : List + """""" + + def __init__(self, type, message, actions): + self.type = type + self.message = message + self.actions = actions + +class MessageActionItem: + """""" + + title : str + """""" + + def __init__(self, title): + self.title = title + +class Range: + """""" + + start : int + """""" + + end : int + """""" + + def __init__(self, start, end): + self.start = start + self.end = end + +class ShowDocumentParams: + """""" + + uri : str + """""" + + external : bool + """""" + + takeFocus : bool + """""" + + selection : Range + """""" + + def __init__(self, uri, external, takeFocus, selection): + self.uri = uri + self.external = external + self.takeFocus = takeFocus + self.selection = selection + +class ShowDocumentResult: + """""" + + success : bool + """""" + + def __init__(self, success): + self.success = success + +class TaskFinishedInfo: + """""" + + def __init__(self, ): + pass + + +class TaskStartedInfo: + """""" + + def __init__(self, ): + pass + + +KEY_DATA_CLASSES = { "ExampleDesc": ExampleDesc,"ProofScriptCommandDesc": ProofScriptCommandDesc,"ProofMacroDesc": ProofMacroDesc,"TraceValue": TraceValue,"SetTraceParams": SetTraceParams,"EnvironmentId": EnvironmentId,"ProofId": ProofId,"TreeNodeDesc": TreeNodeDesc,"TreeNodeId": TreeNodeId,"NodeId": NodeId,"PrintOptions": PrintOptions,"NodeTextId": NodeTextId,"NodeTextDesc": NodeTextDesc,"TermActionId": TermActionId,"TermActionKind": TermActionKind,"TermActionDesc": TermActionDesc,"List": List,"SortDesc": SortDesc,"FunctionDesc": FunctionDesc,"ContractId": ContractId,"ContractDesc": ContractDesc,"LoadParams": LoadParams,"ProblemDefinition": ProblemDefinition,"LogTraceParams": LogTraceParams,"MessageType": MessageType,"ShowMessageParams": ShowMessageParams,"ShowMessageRequestParams": ShowMessageRequestParams,"MessageActionItem": MessageActionItem,"Range": Range,"ShowDocumentParams": ShowDocumentParams,"ShowDocumentResult": ShowDocumentResult,"TaskFinishedInfo": TaskFinishedInfo,"TaskStartedInfo": TaskStartedInfo } + diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java index 2855e390f75..1c6c904553e 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -22,6 +22,8 @@ import java.nio.file.Paths; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; /** * @author Alexander Weigl @@ -43,21 +45,16 @@ public static void main(String[] args) { addClientEndpoint(method); } - try { - Files.writeString(Paths.get("api.meta.json"), getGson().toJson(keyApi)); - } catch (IOException e) { - e.printStackTrace(); - } + runGenerator("api.meta.json", (a) -> () -> getGson().toJson(a)); + runGenerator("api.meta.md", DocGen::new); + runGenerator("keydata.py", PythionGenerator.PyDataGen::new); + runGenerator("server.py", PythionGenerator.PyApiGen::new); + } + private static void runGenerator(String target, Function> api) { try { - var n = new DocGen(keyApi); - Files.writeString(Paths.get("api.meta.md"), n.get()); - } catch (IOException e) { - e.printStackTrace(); - } - try { - var n = new PyGen(keyApi); - Files.writeString(Paths.get("api.py"), n.get()); + var n = api.apply(keyApi); + Files.writeString(Paths.get(target), n.get()); } catch (IOException e) { e.printStackTrace(); } @@ -124,7 +121,7 @@ private static List translate(Parameter[] parameters) { } private static Metamodel.Argument translate(Parameter parameter) { - var type = getOrFindType(parameter.getType()).name(); + var type = getOrFindType(parameter.getType()).name(); return new Metamodel.Argument(parameter.getName(), type); } diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/Metamodel.java index 833699cfe0c..1a868f49a06 100644 --- a/keyext.api.doc/src/main/java/Metamodel.java +++ b/keyext.api.doc/src/main/java/Metamodel.java @@ -41,10 +41,13 @@ record ClientRequest(String name, String documentation, List args, Typ record ClientNotification(String name, String documentation, List args) implements Endpoint { } - record Field(String name, /*Type*/ String type) { + record Field(String name, /*Type*/ String type, String documentation) { + Field(String name, String type) { + this(name, type, ""); + } } - sealed interface Type { + public sealed interface Type { default String kind() { return getClass().getSimpleName(); } diff --git a/keyext.api.doc/src/main/java/PyGen.java b/keyext.api.doc/src/main/java/PyGen.java deleted file mode 100644 index 357c2f51e8d..00000000000 --- a/keyext.api.doc/src/main/java/PyGen.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Comparator; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public class PyGen implements Supplier { - private final Metamodel.KeyApi metamodel; - private PrintWriter out; - private final StringWriter target = new StringWriter(); - - public PyGen(Metamodel.KeyApi metamodel) { - this.metamodel = metamodel; - } - - @Override - public String get() { - try (var out = new PrintWriter(target)) { - this.out = out; - - out.format(""" - import enum - import abc - import typing - from abc import abstractmethod - """); - - metamodel.types().forEach(this::printType); - server( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); - - client( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); - - } - return target.toString(); - } - - private void client(Stream sorted) { - out.format("class Client(abc.AbcMeta):%n"); - sorted.forEach(this::clientEndpoint); - } - - private void clientEndpoint(Metamodel.Endpoint endpoint) { - var args = endpoint.args().stream() - .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) - .collect(Collectors.joining(", ")); - out.format(" @abstractmethod%n"); - if (endpoint instanceof Metamodel.ClientRequest sr) { - out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, asPython(sr.returnType())); - } else { - out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); - } - out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" pass".formatted(endpoint.name(), "")); - out.println(); - out.println(); - } - - private void server(Stream sorted) { - out.format("class KeyServer():%n"); - sorted.forEach(this::serverEndpoint); - } - - private void serverEndpoint(Metamodel.Endpoint endpoint) { - var args = endpoint.args().stream() - .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) - .collect(Collectors.joining(", ")); - if (endpoint instanceof Metamodel.ServerRequest sr) { - out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, - asPython(sr.returnType())); - out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); - out.format(" return self.rpc.call_sync(\"%s\", %s)".formatted(endpoint.name(), "")); - } else { - out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); - out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" return self.rpc.call_async(\"%s\", %s)".formatted(endpoint.name(), "")); - } - out.println(); - out.println(); - } - - private void printType(Metamodel.Type type) { - if (type instanceof Metamodel.ObjectType ot) { - out.format("class %s:%n".formatted(type.name())); - out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); - ot.fields().forEach(it -> out.format(" %s : %s%n".formatted(it.name(), asPython(it.type())))); - } else if (type instanceof Metamodel.EnumType et) { - out.format("class %s(enum.Enum):%n".formatted(type.name())); - out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); - et.values().forEach(it -> out.format(" %s = None%n".formatted(it))); - } - out.println(); - } - - private String asPython(String typeName) { - return switch (typeName) { - case "INT" -> "int"; - case "LONG" -> "int"; - case "STRING" -> "str"; - case "BOOL" -> "bool"; - case "DOUBLE" -> "float"; - default -> { - var t = findType(typeName); - yield asPython(t); - } - }; - } - - private String asPython(Metamodel.Type t) { - if (t instanceof Metamodel.ListType lt) { - return "typing.List[" + asPython(lt.type()) + "]"; - } - - if (t instanceof Metamodel.EitherType lt) { - return "typing.Union[" + asPython(lt.a()) + ", " + asPython(lt.b()) + "]"; - } - return t.name(); - } - - private Metamodel.Type findType(String typeName) { - return this.metamodel.types().stream().filter(it -> it.name().equals(typeName)).findFirst() - .orElseThrow(() -> new RuntimeException("Could not find type: " + typeName)); - } -} \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/PythionGenerator.java b/keyext.api.doc/src/main/java/PythionGenerator.java new file mode 100644 index 00000000000..a4d2018c328 --- /dev/null +++ b/keyext.api.doc/src/main/java/PythionGenerator.java @@ -0,0 +1,223 @@ +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public abstract class PythionGenerator implements Supplier { + protected final Metamodel.KeyApi metamodel; + protected PrintWriter out; + protected final StringWriter target = new StringWriter(); + + public PythionGenerator(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + run(); + } + return target.toString(); + } + + protected abstract void run(); + + protected String asPython(String typeName) { + return switch (typeName) { + case "INT" -> "int"; + case "LONG" -> "int"; + case "STRING" -> "str"; + case "BOOL" -> "bool"; + case "DOUBLE" -> "float"; + default -> { + var t = findType(typeName); + yield asPython(t); + } + }; + } + + protected String asPython(Metamodel.Type t) { + if (t instanceof Metamodel.ListType lt) { + return "typing.List[" + asPython(lt.type()) + "]"; + } + + if (t instanceof Metamodel.EitherType lt) { + return "typing.Union[" + asPython(lt.a()) + ", " + asPython(lt.b()) + "]"; + } + + if (t instanceof Metamodel.BuiltinType bt) { + return switch (bt) { + case INT -> "int"; + case LONG -> "int"; + case STRING -> "str"; + case BOOL -> "bool"; + case DOUBLE -> "float"; + }; + } + return t.name(); + } + + protected Metamodel.Type findType(String typeName) { + return this.metamodel.types().stream().filter(it -> it.name().equals(typeName)).findFirst() + .orElseThrow(() -> new RuntimeException("Could not find type: " + typeName)); + } + + + public static class PyApiGen extends PythionGenerator { + public PyApiGen(Metamodel.KeyApi metamodel) { + super(metamodel); + } + + @Override + protected void run() { + out.format(""" + from __future__ import annotations + from .keydata import * + from .rpc import ServerBase, LspEndpoint + + import enum + import abc + import typing + from abc import abstractmethod + """); + server( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + + client( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + } + + + private void client(Stream sorted) { + out.format("class Client(abc.ABCMeta):%n"); + sorted.forEach(this::clientEndpoint); + } + + private void clientEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + out.format(" @abstractmethod%n"); + if (endpoint instanceof Metamodel.ClientRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, + asPython(sr.returnType())); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + } + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" pass".formatted(endpoint.name(), "")); + out.println(); + out.println(); + } + + private void server(Stream sorted) { + out.format(""" + class KeyServer(ServerBase):%n + def __init__(self, endpoint : LspEndpoint): + super().__init__(endpoint) + + """); + sorted.forEach(this::serverEndpoint); + } + + private void serverEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + + var params = "[]"; + if (!endpoint.args().isEmpty()) { + params = endpoint.args().stream() + .map(Metamodel.Argument::name) + .collect(Collectors.joining(" , ", "[", "]")); + } + + if (endpoint instanceof Metamodel.ServerRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, + asPython(sr.returnType())); + out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); + out.format(" return self._call_sync(\"%s\", %s)".formatted(endpoint.name(), params)); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" return self._call_async(\"%s\", %s)".formatted(endpoint.name(), params)); + } + out.println(); + out.println(); + } + + } + + + public static class PyDataGen extends PythionGenerator { + public PyDataGen(Metamodel.KeyApi metamodel) { + super(metamodel); + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + run(); + } + return target.toString(); + } + + protected void run() { + out.format(""" + from __future__ import annotations + import enum + import abc + import typing + from abc import abstractmethod, ABCMeta + + """); + metamodel.types().forEach(this::printType); + + var names = metamodel.types().stream().map(it -> "\"%s\": %s".formatted(it.name(), it.name())) + .collect(Collectors.joining(",")); + out.format("KEY_DATA_CLASSES = { %s }%n%n", names); + } + + private void printType(Metamodel.Type type) { + if (type instanceof Metamodel.ObjectType ot) { + out.format("class %s:%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n", type.documentation()); + ot.fields().forEach(it -> out.format("%n %s : %s%n \"\"\"%s\"\"\"%n" + .formatted(it.name(), asPython(it.type()), it.documentation()))); + + out.format("\n def __init__(self%s):%n".formatted( + ot.fields().stream() + .map(Metamodel.Field::name) + .collect(Collectors.joining(", ", ", ", "")) + )); + + if (ot.fields().isEmpty()) + out.format(" pass%n%n"); + + for (Metamodel.Field field : ot.fields()) { + out.format(" self.%s = %s%n", field.name(), field.name()); + } + + } else if (type instanceof Metamodel.EnumType et) { + out.format("class %s(enum.Enum):%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); + et.values().forEach(it -> out.format(" %s = None%n".formatted(it))); + } + out.println(); + } + } +} \ No newline at end of file diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index fbbbac93898..71e79884c3d 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -27,5 +27,6 @@ dependencies { compileJava { // for GraalVM options.compilerArgs += ["-Aproject=${project.group}/${project.name}"] + options.compilerArgs += ["-parameters"] // for having parameter name in reflection } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java new file mode 100644 index 00000000000..b8f61b62272 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java @@ -0,0 +1,56 @@ +package org.keyproject.key.api; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +/** + * Stackoverflow post + */ +public class GenericSerializer implements JsonSerializer /*, JsonDeserializer*/ { + + private static final String CLASS_PROPERTY_NAME = "$type"; + private final Gson gson; + + public GenericSerializer() { + gson = new Gson(); + } + + public GenericSerializer(Gson gson) { + this.gson = gson; + } + + /* + @Override + public Object deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + + Class actualClass; + if (json.isJsonObject()) { + JsonObject jsonObject = json.getAsJsonObject(); + String className = jsonObject.get(CLASS_PROPERTY_NAME).getAsString(); + try { + actualClass = Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new JsonParseException(e.getMessage()); + } + } else { + actualClass = typeOfT.getClass(); + } + + return gson.fromJson(json, actualClass); + } + */ + + @Override + public JsonElement serialize(Object src, Type typeOfSrc, + JsonSerializationContext context) { + JsonElement retValue = gson.toJsonTree(src); + if (retValue.isJsonObject()) { + retValue.getAsJsonObject().addProperty(CLASS_PROPERTY_NAME, src.getClass().getName()); + } + return retValue; + } + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index 7ff86ae2c09..f2a28731d3a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -75,7 +75,8 @@ public KeyApiImpl() { @JsonRequest public CompletableFuture> examples() { return CompletableFutures.computeAsync((c) -> - ExampleChooser.listExamples(ExampleChooser.lookForExamples()).stream().map(it -> ExampleDesc.from(it)).toList()); + ExampleChooser.listExamples(ExampleChooser.lookForExamples()) + .stream().map(ExampleDesc::from).toList()); } @Override diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index b95ae6eebe2..26981875aef 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -26,8 +26,6 @@ public class StartServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); - private static KeyAdapter adapter; - //region CLI arguments @Option(names = "--std", description = "use stdout and stdin for communication") boolean stdStreams; @@ -146,7 +144,9 @@ public void run() { public static void configureJson(GsonBuilder gsonBuilder) { - adapter = new KeyAdapter(gsonBuilder); + gsonBuilder.registerTypeHierarchyAdapter(Object.class, new GenericSerializer()); + gsonBuilder.registerTypeAdapter(File.class, new KeyAdapter.FileTypeAdapter()); + } public static Launcher launch(OutputStream out, InputStream in, KeyApiImpl keyApi) { @@ -167,3 +167,4 @@ public static Launcher launch(OutputStream out, InputStream in, KeyAp return launcherBuilder.create(); } } + diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 68b330491fc..c17647c9e4f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -48,7 +48,7 @@ public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationCo } } - static class FileTypeAdapter extends TypeAdapter { + public static class FileTypeAdapter extends TypeAdapter { @Override public void write(JsonWriter out, File value) throws IOException { out.value(value.toString()); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java index 5e5f4f1410b..49e662c6524 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java @@ -1,5 +1,7 @@ package org.keyproject.key.api.remoteclient; +import java.util.List; + public record ShowMessageRequestParams( /** * The message type. See {@link MessageType} @@ -15,6 +17,6 @@ public record ShowMessageRequestParams( * The message action items to present. * */ - MessageActionItem[] actions + List actions ) { } \ No newline at end of file diff --git a/keyext.client.python/keyapi/__init__.py b/keyext.client.python/keyapi/__init__.py index 4a913b39b2e..4807ec5ee59 100644 --- a/keyext.client.python/keyapi/__init__.py +++ b/keyext.client.python/keyapi/__init__.py @@ -1,8 +1,8 @@ -from keyapi.rpc import * +import abc +from abc import abstractmethod, ABCMeta + +from keyapi.keydata import * +from keyapi.rpc import LspEndpoint + -class KeyStub(JsonRPCHandler): - def __init__(self, input, output): - super().__init__(input, output) - def list_examples(self): - return self._send("examples/list", []) diff --git a/keyext.client.python/keyapi/keydata.py b/keyext.client.python/keyapi/keydata.py new file mode 100644 index 00000000000..dfeaf76f7c7 --- /dev/null +++ b/keyext.client.python/keyapi/keydata.py @@ -0,0 +1,533 @@ +from __future__ import annotations +import enum +import abc +import typing +from abc import abstractmethod, ABCMeta + + +class ExampleDesc: + """""" + + name: str + """""" + + description: str + """""" + + def __init__(self, name, description): + self.name = name + self.description = description + + +class ProofScriptCommandDesc: + """""" + + def __init__(self, ): + pass + + +class ProofMacroDesc: + """""" + + name: str + """""" + + category: str + """""" + + description: str + """""" + + scriptCommandName: str + """""" + + def __init__(self, name, category, description, scriptCommandName): + self.name = name + self.category = category + self.description = description + self.scriptCommandName = scriptCommandName + + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + + +class SetTraceParams: + """""" + + value: TraceValue + """""" + + def __init__(self, value): + self.value = value + + +class EnvironmentId: + """""" + + envId: str + """""" + + def __init__(self, envId): + self.envId = envId + + +class ProofId: + """""" + + env: EnvironmentId + """""" + + proofId: str + """""" + + def __init__(self, env, proofId): + self.env = env + self.proofId = proofId + + +class TreeNodeDesc: + """""" + + def __init__(self, ): + pass + + +class TreeNodeId: + """""" + + id: str + """""" + + def __init__(self, id): + self.id = id + + +class NodeId: + """""" + + proofId: ProofId + """""" + + nodeId: int + """""" + + def __init__(self, proofId, nodeId): + self.proofId = proofId + self.nodeId = nodeId + + +class PrintOptions: + """""" + + unicode: bool + """""" + + width: int + """""" + + indentation: int + """""" + + pure: bool + """""" + + termLabels: bool + """""" + + def __init__(self, unicode, width, indentation, pure, termLabels): + self.unicode = unicode + self.width = width + self.indentation = indentation + self.pure = pure + self.termLabels = termLabels + + +class NodeTextId: + """""" + + nodeId: NodeId + """""" + + nodeTextId: int + """""" + + def __init__(self, nodeId, nodeTextId): + self.nodeId = nodeId + self.nodeTextId = nodeTextId + + +class NodeTextDesc: + """""" + + id: NodeTextId + """""" + + result: str + """""" + + def __init__(self, id, result): + self.id = id + self.result = result + + +class TermActionId: + """""" + + nodeId: NodeId + """""" + + pio: str + """""" + + id: str + """""" + + def __init__(self, nodeId, pio, id): + self.nodeId = nodeId + self.pio = pio + self.id = id + + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + + +class TermActionDesc: + """""" + + commandId: TermActionId + """""" + + displayName: str + """""" + + description: str + """""" + + category: str + """""" + + kind: TermActionKind + """""" + + def __init__(self, commandId, displayName, description, category, kind): + self.commandId = commandId + self.displayName = displayName + self.description = description + self.category = category + self.kind = kind + + +class List: + """""" + + def __init__(self, ): + pass + + +class SortDesc: + """""" + + string: str + """""" + + documentation: str + """""" + + extendsSorts: List + """""" + + anAbstract: bool + """""" + + s: str + """""" + + def __init__(self, string, documentation, extendsSorts, anAbstract, s): + self.string = string + self.documentation = documentation + self.extendsSorts = extendsSorts + self.anAbstract = anAbstract + self.s = s + + +class FunctionDesc: + """""" + + name: str + """""" + + sort: str + """""" + + retSort: SortDesc + """""" + + argSorts: List + """""" + + rigid: bool + """""" + + unique: bool + """""" + + skolemConstant: bool + """""" + + def __init__(self, name, sort, retSort, argSorts, rigid, unique, skolemConstant): + self.name = name + self.sort = sort + self.retSort = retSort + self.argSorts = argSorts + self.rigid = rigid + self.unique = unique + self.skolemConstant = skolemConstant + + +class ContractId: + """""" + + envId: EnvironmentId + """""" + + contractId: int + """""" + + def __init__(self, envId, contractId): + self.envId = envId + self.contractId = contractId + + +class ContractDesc: + """""" + + contractId: ContractId + """""" + + name: str + """""" + + displayName: str + """""" + + typeName: str + """""" + + htmlText: str + """""" + + plainText: str + """""" + + def __init__(self, contractId, name, displayName, typeName, htmlText, plainText): + self.contractId = contractId + self.name = name + self.displayName = displayName + self.typeName = typeName + self.htmlText = htmlText + self.plainText = plainText + + +class LoadParams: + """""" + + keyFile: str + """""" + + javaFile: str + """""" + + classPath: List + """""" + + bootClassPath: str + """""" + + includes: List + """""" + + def __init__(self, keyFile, javaFile, classPath, bootClassPath, includes): + self.keyFile = keyFile + self.javaFile = javaFile + self.classPath = classPath + self.bootClassPath = bootClassPath + self.includes = includes + + + +class ProblemDefinition: + """""" + + sorts: List + """""" + + functions: List + """""" + + predicates: List + """""" + + antecTerms: List + """""" + + succTerms: List + """""" + + def __init__(self, sorts, functions, predicates, antecTerms, succTerms): + self.sorts = sorts + self.functions = functions + self.predicates = predicates + self.antecTerms = antecTerms + self.succTerms = succTerms + + +class LogTraceParams: + """""" + + messag: str + """""" + + verbose: str + """""" + + def __init__(self, messag, verbose): + self.messag = messag + self.verbose = verbose + + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + + +class ShowMessageParams: + """""" + + type: MessageType + """""" + + message: str + """""" + + def __init__(self, type, message): + self.type = type + self.message = message + + +class ShowMessageRequestParams: + """""" + + type: MessageType + """""" + + message: str + """""" + + actions: List + """""" + + def __init__(self, type, message, actions): + self.type = type + self.message = message + self.actions = actions + + +class MessageActionItem: + """""" + + title: str + """""" + + def __init__(self, title): + self.title = title + + +class Range: + """""" + + start: int + """""" + + end: int + """""" + + def __init__(self, start, end): + self.start = start + self.end = end + + +class ShowDocumentParams: + """""" + + uri: str + """""" + + external: bool + """""" + + takeFocus: bool + """""" + + selection: Range + """""" + + def __init__(self, uri, external, takeFocus, selection): + self.uri = uri + self.external = external + self.takeFocus = takeFocus + self.selection = selection + + +class ShowDocumentResult: + """""" + + success: bool + """""" + + def __init__(self, success): + self.success = success + + +class TaskFinishedInfo: + """""" + + def __init__(self, ): + pass + + +class TaskStartedInfo: + """""" + + def __init__(self, ): + pass + + +KEY_DATA_CLASSES = {"ExampleDesc": ExampleDesc, "ProofScriptCommandDesc": ProofScriptCommandDesc, + "ProofMacroDesc": ProofMacroDesc, "TraceValue": TraceValue, "SetTraceParams": SetTraceParams, + "EnvironmentId": EnvironmentId, "ProofId": ProofId, "TreeNodeDesc": TreeNodeDesc, + "TreeNodeId": TreeNodeId, "NodeId": NodeId, "PrintOptions": PrintOptions, "NodeTextId": NodeTextId, + "NodeTextDesc": NodeTextDesc, "TermActionId": TermActionId, "TermActionKind": TermActionKind, + "TermActionDesc": TermActionDesc, "List": List, "SortDesc": SortDesc, "FunctionDesc": FunctionDesc, + "ContractId": ContractId, "ContractDesc": ContractDesc, "LoadParams": LoadParams, + "ProblemDefinition": ProblemDefinition, "LogTraceParams": LogTraceParams, + "MessageType": MessageType, "ShowMessageParams": ShowMessageParams, + "ShowMessageRequestParams": ShowMessageRequestParams, "MessageActionItem": MessageActionItem, + "Range": Range, "ShowDocumentParams": ShowDocumentParams, "ShowDocumentResult": ShowDocumentResult, + "TaskFinishedInfo": TaskFinishedInfo, "TaskStartedInfo": TaskStartedInfo} diff --git a/keyext.client.python/keyapi/rpc.py b/keyext.client.python/keyapi/rpc.py index 02ba2be474b..c112055e006 100644 --- a/keyext.client.python/keyapi/rpc.py +++ b/keyext.client.python/keyapi/rpc.py @@ -1,10 +1,11 @@ import enum import json -import sys import threading -from io import TextIOWrapper +import typing from typing import Dict +from keyapi import KEY_DATA_CLASSES + JSON_RPC_REQ_FORMAT = "Content-Length: {json_string_len}\r\n\r\n{json_string}" LEN_HEADER = "Content-Length: " TYPE_HEADER = "Content-Type: " @@ -16,16 +17,20 @@ class MyEncoder(json.JSONEncoder): """ def default(self, o): # pylint: disable=E0202 - return o.__dict__ + d = dict(o.__dict__) + d['$type'] = type(o).__name__ + return d class ResponseError(Exception): - def __init__(self, error_code, message): + def __init__(self, error_code, message, data=None): super().__init__(message) self.error_code = error_code + self.data = data class ErrorCodes(enum.Enum): + MethodNotFound = None ParseError = 1 @@ -57,27 +62,27 @@ def send_request(self, message): :param dict message: The message to send. ''' - json_string = json.dumps(message, cls=MyEncoder) + json_string = json.dumps(message , cls=MyEncoder) jsonrpc_req = self.__add_header(json_string) with self.write_lock: - self.stdin.write(jsonrpc_req.encode()) - self.stdin.flush() + self.stdout.write(jsonrpc_req) + self.stdout.flush() - def recv_response(self): + def recv_response(self) -> object: ''' Recives a message. :return: a message ''' - with self.read_lock: + with (self.read_lock): message_size = None while True: # read header - line = self.stdout.readline() + line = self.stdin.readline() if not line: # server quit return None - line = line.decode("utf-8") + # line = line.decode("utf-8") if not line.endswith("\r\n"): raise ResponseError(ErrorCodes.ParseError, "Bad header: missing newline") # remove the "\r\n" @@ -99,12 +104,18 @@ def recv_response(self): if not message_size: raise ResponseError(ErrorCodes.ParseError, "Bad header: missing size") - jsonrpc_res = self.stdout.read(message_size).decode("utf-8") - return json.loads(jsonrpc_res) + jsonrpc_res = self.stdin.read(message_size) # .decode("utf-8") + return json.loads(jsonrpc_res, object_hook=object_decoder) + + +def object_decoder(obj): + if '$type' in obj: + return KEY_DATA_CLASSES[obj["$type"]](**obj) + return obj class LspEndpoint(threading.Thread): - def __init__(self, json_rpc_endpoint: JsonRpcEndpoint, method_callbacks=None, notify_callbacks=None, timeout=2): + def __init__(self, json_rpc_endpoint: JsonRpcEndpoint, method_callbacks=None, notify_callbacks=None, timeout=2000): super().__init__() self.json_rpc_endpoint: JsonRpcEndpoint = json_rpc_endpoint self.notify_callbacks: Dict = notify_callbacks or {} @@ -126,6 +137,7 @@ def stop(self): self.shutdown_flag = True def run(self): + rpc_id = None while not self.shutdown_flag: try: jsonrpc_message = self.json_rpc_endpoint.recv_response() @@ -175,14 +187,14 @@ def send_message(self, method_name, params, id=None): message_dict["params"] = params self.json_rpc_endpoint.send_request(message_dict) - def call_method(self, method_name, **kwargs): + def call_method(self, method_name, args): current_id = self.next_id self.next_id += 1 cond = threading.Condition() self.event_dict[current_id] = cond cond.acquire() - self.send_message(method_name, kwargs, current_id) + self.send_message(method_name, args, current_id) if self.shutdown_flag: return None @@ -196,5 +208,17 @@ def call_method(self, method_name, **kwargs): raise ResponseError(error.get("code"), error.get("message"), error.get("data")) return result - def send_notification(self, method_name, **kwargs): + def send_notification(self, method_name, kwargs): self.send_message(method_name, kwargs) + + +class ServerBase: + def __init__(self, endpoint: LspEndpoint): + self.endpoint = endpoint + + def _call_sync(self, method_name: str, param: typing.List[object]) -> object: + resp = self.endpoint.call_method(method_name, param) + return resp + + def _call_async(self, method_name: str, param: typing.List[object]): + self.endpoint.send_notification(method_name, param) diff --git a/keyext.client.python/keyapi/server.py b/keyext.client.python/keyapi/server.py new file mode 100644 index 00000000000..2940363e1c2 --- /dev/null +++ b/keyext.client.python/keyapi/server.py @@ -0,0 +1,161 @@ +from __future__ import annotations + +import abc +from abc import abstractmethod + +from .keydata import * +from .rpc import ServerBase, LspEndpoint + + +# noinspection PyTypeChecker +class KeyServer(ServerBase): + + def __init__(self, endpoint: LspEndpoint): + super().__init__(endpoint) + + def env_contracts(self, env: EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self._call_sync("env/contracts", [env]) + + def env_functions(self, env: EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self._call_sync("env/functions", [env]) + + def env_openContract(self, contractId: ContractId) -> ProofId: + """""" + + return self._call_sync("env/openContract", [contractId]) + + def env_sorts(self, env: EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self._call_sync("env/sorts", [env]) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self._call_sync("examples/list", []) + + def goal_actions(self, id: NodeTextId, pos: int) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/actions", [id, pos]) + + def goal_apply_action(self, id: TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/apply_action", [id]) + + def goal_free(self, id: NodeTextId): + """""" + + return self._call_async("goal/free", [id]) + + def goal_print(self, id: NodeId, options: PrintOptions) -> NodeTextDesc: + """""" + + return self._call_sync("goal/print", [id, options]) + + def loading_load(self, params: LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self._call_sync("loading/load", [params]) + + def loading_loadExample(self, id: str) -> ProofId: + """""" + + return self._call_sync("loading/loadExample", [id]) + + def loading_loadKey(self, content: str) -> ProofId: + """""" + + return self._call_sync("loading/loadKey", [content]) + + def loading_loadProblem(self, problem: ProblemDefinition) -> ProofId: + """""" + + return self._call_sync("loading/loadProblem", [problem]) + + def loading_loadTerm(self, term: str) -> ProofId: + """""" + + return self._call_sync("loading/loadTerm", [term]) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self._call_sync("meta/available_macros", []) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self._call_sync("meta/available_script_commands", []) + + def meta_version(self, ) -> str: + """""" + + return self._call_sync("meta/version", []) + + def proofTree_children(self, proof: ProofId, nodeId: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/children", [proof, nodeId]) + + def proofTree_root(self, id: ProofId) -> TreeNodeDesc: + """""" + + return self._call_sync("proofTree/root", [id]) + + def proofTree_subtree(self, proof: ProofId, nodeId: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/subtree", [proof, nodeId]) + + def server_exit(self, ): + """""" + + return self._call_async("server/exit", []) + + def server_setTrace(self, params: SetTraceParams): + """""" + + return self._call_async("server/setTrace", [params]) + + def server_shutdown(self, ) -> bool: + """""" + + return self._call_sync("server/shutdown", []) + + +class Client(abc.ABCMeta): + @abstractmethod + def client_logTrace(self, params: LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, e: str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, params: ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, params: ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, params: ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass diff --git a/keyext.client.python/main.py b/keyext.client.python/main.py index a5cb45321d8..d12fadea42a 100644 --- a/keyext.client.python/main.py +++ b/keyext.client.python/main.py @@ -1,5 +1,7 @@ import socket -from keyapi import KeyStub, KeyClient +from keyapi import LspEndpoint, LoadParams +from keyapi.server import KeyServer +from keyapi.rpc import JsonRpcEndpoint if __name__ == "__main__": target = ("localhost", 5151) @@ -8,6 +10,18 @@ s.connect(target) input = s.makefile("r", newline="\r\n") output = s.makefile("w", newline="\r\n") - stub = KeyStub(input, output) - stub.client = KeyClient() - print(stub.list_examples()) + + rpc_endpoint = JsonRpcEndpoint(input, output) + endpoint = LspEndpoint(rpc_endpoint) + endpoint.start() + + key = KeyServer(endpoint) + print(key.meta_version()) + ex = key.examples_list() + print(ex) + + proofHandle = key.loading_load( + LoadParams("/home/weigl/work/key/key.ui/examples/standard_key/prop_log/contraposition.key", + None, None, None, None)) + + print(proofHandle) diff --git a/keyext.client.python/rwtest.py b/keyext.client.python/rwtest.py deleted file mode 100644 index 312532192dc..00000000000 --- a/keyext.client.python/rwtest.py +++ /dev/null @@ -1,402 +0,0 @@ -import enum -import abc -import typing -from abc import abstractmethod - - -class ExampleDesc: - """""" - - name: str - description: str - - -class ProofScriptCommandDesc: - """""" - - -class ProofMacroDesc: - """""" - - name: str - category: str - description: str - scriptCommandName: str - - -class TraceValue(enum.Enum): - """""" - - Off = None - Message = None - All = None - - -class SetTraceParams: - """""" - - value: TraceValue - - -class EnvironmentId: - """""" - - envId: str - - -class ProofId: - """""" - - env: EnvironmentId - proofId: str - - -class TreeNodeDesc: - """""" - - -class TreeNodeId: - """""" - - id: str - - -class NodeId: - """""" - - proofId: ProofId - nodeId: int - - -class PrintOptions: - """""" - - unicode: bool - width: int - indentation: int - pure: bool - termLabels: bool - - -class NodeTextId: - """""" - - nodeId: NodeId - nodeTextId: int - - -class NodeTextDesc: - """""" - - id: NodeTextId - result: str - - -class TermActionId: - """""" - - nodeId: NodeId - pio: str - id: str - - -class TermActionKind(enum.Enum): - """""" - - BuiltIn = None - Script = None - Macro = None - Taclet = None - - -class TermActionDesc: - """""" - - commandId: TermActionId - displayName: str - description: str - category: str - kind: TermActionKind - - -class List: - """""" - - -class SortDesc: - """""" - - string: str - documentation: str - extendsSorts: List - anAbstract: bool - s: str - - -class FunctionDesc: - """""" - - name: str - sort: str - retSort: SortDesc - argSorts: List - rigid: bool - unique: bool - skolemConstant: bool - - -class ContractId: - """""" - - envId: EnvironmentId - contractId: int - - -class ContractDesc: - """""" - - contractId: ContractId - name: str - displayName: str - typeName: str - htmlText: str - plainText: str - - -class LoadParams: - """""" - - keyFile: str - javaFile: str - classPath: List - bootClassPath: str - includes: List - - -class ProblemDefinition: - """""" - - sorts: List - functions: List - predicates: List - antecTerms: List - succTerms: List - - -class LogTraceParams: - """""" - - messag: str - verbose: str - - -class MessageType(enum.Enum): - """""" - - Unused = None - Error = None - Warning = None - Info = None - Log = None - Debug = None - - -class ShowMessageParams: - """""" - - type: MessageType - message: str - - - -class ShowMessageRequestParams: - """""" - - type: MessageType - message: str - actions: typing.List[MessageActionItem] - - -class MessageActionItem: - """""" - - title: str - - -class Range: - """""" - - start: int - end: int - - -class ShowDocumentParams: - """""" - - uri: str - external: bool - takeFocus: bool - selection: Range - - -class ShowDocumentResult: - """""" - - success: bool - - -class TaskFinishedInfo: - """""" - - -class TaskStartedInfo: - """""" - - -class KeyServer(): - def env_contracts(self, arg0: EnvironmentId) -> typing.List[ContractDesc]: - """""" - - return self.rpc.call_sync("env/contracts", ) - - def env_functions(self, arg0: EnvironmentId) -> typing.List[FunctionDesc]: - """""" - - return self.rpc.call_sync("env/functions", ) - - def env_openContract(self, arg0: ContractId) -> ProofId: - """""" - - return self.rpc.call_sync("env/openContract", ) - - def env_sorts(self, arg0: EnvironmentId) -> typing.List[SortDesc]: - """""" - - return self.rpc.call_sync("env/sorts", ) - - def examples_list(self, ) -> typing.List[ExampleDesc]: - """""" - - return self.rpc.call_sync("examples/list", ) - - def goal_actions(self, arg0: NodeTextId, arg1: int) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/actions", ) - - def goal_apply_action(self, arg0: TermActionId) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/apply_action", ) - - def goal_free(self, arg0: NodeTextId): - """""" - - return self.rpc.call_async("goal/free", ) - - def goal_print(self, arg0: NodeId, arg1: PrintOptions) -> NodeTextDesc: - """""" - - return self.rpc.call_sync("goal/print", ) - - def loading_load(self, arg0: LoadParams) -> typing.Union[EnvironmentId, ProofId]: - """""" - - return self.rpc.call_sync("loading/load", ) - - def loading_loadExample(self, arg0: str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadExample", ) - - def loading_loadKey(self, arg0: str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadKey", ) - - def loading_loadProblem(self, arg0: ProblemDefinition) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadProblem", ) - - def loading_loadTerm(self, arg0: str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadTerm", ) - - def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: - """""" - - return self.rpc.call_sync("meta/available_macros", ) - - def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: - """""" - - return self.rpc.call_sync("meta/available_script_commands", ) - - def meta_version(self, ) -> str: - """""" - - return self.rpc.call_sync("meta/version", ) - - def proofTree_children(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/children", ) - - def proofTree_root(self, arg0: ProofId) -> TreeNodeDesc: - """""" - - return self.rpc.call_sync("proofTree/root", ) - - def proofTree_subtree(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/subtree", ) - - def server_exit(self, ): - """""" - - return self.rpc.call_async("server/exit", ) - - def server_setTrace(self, arg0: SetTraceParams): - """""" - - return self.rpc.call_async("server/setTrace", ) - - def server_shutdown(self, ) -> bool: - """""" - - return self.rpc.call_sync("server/shutdown", ) - - -class Client(abc.ABCMeta): - @abstractmethod - def client_logTrace(self, arg0: LogTraceParams): - """""" - - pass - - @abstractmethod - def client_sayHello(self, arg0: str): - """""" - - pass - - @abstractmethod - def client_showDocument(self, arg0: ShowDocumentParams) -> ShowDocumentResult: - """""" - - pass - - @abstractmethod - def client_sm(self, arg0: ShowMessageParams): - """""" - - pass - - @abstractmethod - def client_userResponse(self, arg0: ShowMessageRequestParams) -> MessageActionItem: - """""" - - pass diff --git a/server.py b/server.py new file mode 100644 index 00000000000..7ad103297fe --- /dev/null +++ b/server.py @@ -0,0 +1,159 @@ +from __future__ import annotations +from .keydata import * +from .rpc import ServerBase + +import enum +import abc +import typing +from abc import abstractmethod +class KeyServer(ServerBase): + + def __init__(self, endpoint : LspEndpoint): + super().__init__(endpoint) + + def env_contracts(self, env : EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self._call_sync("env/contracts", [env]) + + def env_functions(self, env : EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self._call_sync("env/functions", [env]) + + def env_openContract(self, contractId : ContractId) -> ProofId: + """""" + + return self._call_sync("env/openContract", [contractId]) + + def env_sorts(self, env : EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self._call_sync("env/sorts", [env]) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self._call_sync("examples/list", []) + + def goal_actions(self, id : NodeTextId, pos : int) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/actions", [id , pos]) + + def goal_apply_action(self, id : TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/apply_action", [id]) + + def goal_free(self, id : NodeTextId): + """""" + + return self._call_async("goal/free", [id]) + + def goal_print(self, id : NodeId, options : PrintOptions) -> NodeTextDesc: + """""" + + return self._call_sync("goal/print", [id , options]) + + def loading_load(self, params : LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self._call_sync("loading/load", [params]) + + def loading_loadExample(self, id : str) -> ProofId: + """""" + + return self._call_sync("loading/loadExample", [id]) + + def loading_loadKey(self, content : str) -> ProofId: + """""" + + return self._call_sync("loading/loadKey", [content]) + + def loading_loadProblem(self, problem : ProblemDefinition) -> ProofId: + """""" + + return self._call_sync("loading/loadProblem", [problem]) + + def loading_loadTerm(self, term : str) -> ProofId: + """""" + + return self._call_sync("loading/loadTerm", [term]) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self._call_sync("meta/available_macros", []) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self._call_sync("meta/available_script_commands", []) + + def meta_version(self, ) -> str: + """""" + + return self._call_sync("meta/version", []) + + def proofTree_children(self, proof : ProofId, nodeId : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/children", [proof , nodeId]) + + def proofTree_root(self, id : ProofId) -> TreeNodeDesc: + """""" + + return self._call_sync("proofTree/root", [id]) + + def proofTree_subtree(self, proof : ProofId, nodeId : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/subtree", [proof , nodeId]) + + def server_exit(self, ): + """""" + + return self._call_async("server/exit", []) + + def server_setTrace(self, params : SetTraceParams): + """""" + + return self._call_async("server/setTrace", [params]) + + def server_shutdown(self, ) -> bool: + """""" + + return self._call_sync("server/shutdown", []) + +class Client(abc.ABCMeta): + @abstractmethod + def client_logTrace(self, params : LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, e : str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, params : ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, params : ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, params : ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass + From d2dcd70e0e7f44919ddbf81c3be46a5c11dfda97 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Fri, 3 Nov 2023 17:58:48 +0100 Subject: [PATCH 08/50] add throwable adapter --- .../main/java/org/keyproject/key/api/StartServer.java | 2 +- .../org/keyproject/key/api/adapters/KeyAdapter.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index 26981875aef..b0491145cda 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -146,7 +146,7 @@ public void run() { public static void configureJson(GsonBuilder gsonBuilder) { gsonBuilder.registerTypeHierarchyAdapter(Object.class, new GenericSerializer()); gsonBuilder.registerTypeAdapter(File.class, new KeyAdapter.FileTypeAdapter()); - + gsonBuilder.registerTypeAdapter(Throwable.class, new KeyAdapter.ThrowableAdapter()); } public static Launcher launch(OutputStream out, InputStream in, KeyApiImpl keyApi) { diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index c17647c9e4f..67871cec674 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -74,6 +74,17 @@ public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationCont } } + public static class ThrowableAdapter implements JsonSerializer { + @Override + public JsonElement serialize(Throwable src, Type typeOfSrc, JsonSerializationContext context) { + var obj = new JsonObject(); + obj.add("$class", context.serialize(src.getClass().getSimpleName())); + obj.add("message", context.serialize(src.getMessage())); + obj.add("cause", context.serialize(src.getCause())); + return obj; + } + } + /*class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { @Override public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { From 6887838b8bf7118dff539a0a62069435903abe0f Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sat, 18 Nov 2023 19:43:59 +0100 Subject: [PATCH 09/50] spotless and merge errors --- .../src/main/java/org/key_project/Main.java | 3 +- .../AbstractSymbolicExecutionTestCase.java | 1546 +++++++++-------- .../key/control/AbstractProofControl.java | 3 +- .../ilkd/key/control/DefaultProofControl.java | 27 +- .../uka/ilkd/key/control/KeYEnvironment.java | 125 +- .../de/uka/ilkd/key/control/ProofControl.java | 5 +- .../uka/ilkd/key/macros/ProofMacroFacade.java | 3 +- .../key/macros/ProofMacroFinishedInfo.java | 1 - .../scripts/ProofScriptCommandFacade.java | 4 +- .../main/java/de/uka/ilkd/key/proof/Goal.java | 2 +- .../main/java/de/uka/ilkd/key/proof/Node.java | 33 +- .../speclang/njml/ContractLoadingTests.java | 27 +- .../java/de/uka/ilkd/key/gui/Example.java | 24 +- .../de/uka/ilkd/key/gui/ProofMacroWorker.java | 25 +- .../key/gui/actions/RunAllProofsAction.java | 18 +- keyext.api.doc/src/main/java/DocGen.java | 165 +- .../src/main/java/ExtractMetaData.java | 99 +- keyext.api.doc/src/main/java/Metamodel.java | 86 +- .../src/main/java/PythionGenerator.java | 61 +- .../keyproject/key/api/GenericSerializer.java | 55 +- .../org/keyproject/key/api/KeyApiImpl.java | 153 +- .../org/keyproject/key/api/NodeTextId.java | 6 +- .../org/keyproject/key/api/StartServer.java | 34 +- .../keyproject/key/api/TermActionUtil.java | 91 +- .../key/api/adapters/KeyAdapter.java | 89 +- .../key/api/adapters/package-info.java | 2 +- .../keyproject/key/api/data/ContractDesc.java | 3 + .../keyproject/key/api/data/FunctionDesc.java | 7 +- .../key/api/data/KeyIdentifications.java | 33 +- .../keyproject/key/api/data/LoadParams.java | 3 + .../key/api/data/MacroDescription.java | 3 + .../key/api/data/MacroStatistic.java | 8 +- .../org/keyproject/key/api/data/NodeDesc.java | 7 +- .../keyproject/key/api/data/NodeTextDesc.java | 3 + .../key/api/data/PredicateDesc.java | 3 + .../key/api/data/ProblemDefinition.java | 7 +- .../key/api/data/ProofMacroDesc.java | 3 + .../key/api/data/ProofScriptCommandDesc.java | 3 + .../org/keyproject/key/api/data/SortDesc.java | 7 +- .../key/api/data/StreategyOptions.java | 3 + .../key/api/data/TermActionDesc.java | 3 + .../key/api/data/TermActionKind.java | 3 + .../keyproject/key/api/data/TraceValue.java | 3 + .../keyproject/key/api/data/TreeNodeDesc.java | 3 + .../keyproject/key/api/internal/NodeText.java | 5 +- .../keyproject/key/api/remoteapi/EnvApi.java | 9 +- .../key/api/remoteapi/ExampleApi.java | 10 +- .../key/api/remoteapi/ExampleDesc.java | 3 + .../keyproject/key/api/remoteapi/GoalApi.java | 11 +- .../keyproject/key/api/remoteapi/KeyApi.java | 6 +- .../keyproject/key/api/remoteapi/MetaApi.java | 11 +- .../key/api/remoteapi/PrintOptions.java | 3 + .../key/api/remoteapi/ProofApi.java | 16 +- .../key/api/remoteapi/ProofLoadApi.java | 17 +- .../key/api/remoteapi/ProofTreeApi.java | 9 +- .../key/api/remoteapi/ServerManagement.java | 20 +- .../key/api/remoteclient/ClientApi.java | 34 +- .../api/remoteclient/LogMessageParams.java | 3 + .../key/api/remoteclient/LogTraceParams.java | 3 + .../api/remoteclient/MessageActionItem.java | 3 + .../key/api/remoteclient/MessageType.java | 53 +- .../api/remoteclient/ShowDocumentParams.java | 3 + .../api/remoteclient/ShowDocumentResult.java | 3 + .../api/remoteclient/ShowMessageParams.java | 5 +- .../ShowMessageRequestParams.java | 3 + .../org/keyproject/key/api/SimpleClient.java | 10 +- .../java/org/keyproject/key/api/TestRpc.java | 19 +- .../ProofExplorationServiceTest.java | 38 +- .../ilkd/key/gui/testgen/TGInfoDialog.java | 9 +- 69 files changed, 1681 insertions(+), 1417 deletions(-) diff --git a/key.core.example/src/main/java/org/key_project/Main.java b/key.core.example/src/main/java/org/key_project/Main.java index 4da18d230e9..37530b71aa4 100644 --- a/key.core.example/src/main/java/org/key_project/Main.java +++ b/key.core.example/src/main/java/org/key_project/Main.java @@ -131,7 +131,8 @@ private static List getContracts(KeYEnvironment env) { * @param env the {@link KeYEnvironment} in which to prove the contract * @param contract the {@link Contract} to be proven */ - private static void proveContract(KeYEnvironment env, Contract contract) throws InterruptedException { + private static void proveContract(KeYEnvironment env, Contract contract) + throws InterruptedException { Proof proof = null; try { // Create proof diff --git a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java index 907a15d5c9d..ba7074ce7f7 100644 --- a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java +++ b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java @@ -44,6 +44,7 @@ import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionUtil; import de.uka.ilkd.key.util.HelperClassForTests; import de.uka.ilkd.key.util.KeYConstants; + import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableList; @@ -51,15 +52,11 @@ import org.key_project.util.helper.FindResources; import org.key_project.util.java.CollectionUtil; import org.key_project.util.java.StringUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.util.*; - import static org.junit.jupiter.api.Assertions.*; /** @@ -69,7 +66,7 @@ */ public abstract class AbstractSymbolicExecutionTestCase { private static final Logger LOGGER = - LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); + LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); /** *

    @@ -86,7 +83,7 @@ public abstract class AbstractSymbolicExecutionTestCase { *

    */ public static final boolean CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY = - Boolean.getBoolean("UPDATE_TEST_ORACLE"); + Boolean.getBoolean("UPDATE_TEST_ORACLE"); static { @@ -102,13 +99,13 @@ public abstract class AbstractSymbolicExecutionTestCase { * Number of executed SET nodes to execute all in one. */ public static final int ALL_IN_ONE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; /** * Number of executed SET nodes for only one SET node per auto mode run. */ public static final int SINGLE_SET_NODE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; /** * Default stop conditions of executed SET nodes. @@ -135,9 +132,9 @@ public abstract class AbstractSymbolicExecutionTestCase { static { // Define fast mode if (FAST_MODE) { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN}; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN }; } else { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN}; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN }; } // Create temporary director for oracle files if required. File directory = null; @@ -160,18 +157,18 @@ public abstract class AbstractSymbolicExecutionTestCase { /** * Creates a new oracle file. * - * @param node The node to save as oracle file. + * @param node The node to save as oracle file. * @param oraclePathInBaseDirFile The path in example directory. - * @param saveConstraints Save constraints? - * @param saveVariables Save variables? - * @param saveCallStack Save call stack? - * @param saveReturnValues Save method return values? - * @throws IOException Occurred Exception + * @param saveConstraints Save constraints? + * @param saveVariables Save variables? + * @param saveCallStack Save call stack? + * @param saveReturnValues Save method return values? + * @throws IOException Occurred Exception * @throws ProofInputException Occurred Exception */ protected static void createOracleFile(IExecutionNode node, String oraclePathInBaseDirFile, - boolean saveConstraints, boolean saveVariables, boolean saveCallStack, - boolean saveReturnValues) throws IOException, ProofInputException { + boolean saveConstraints, boolean saveVariables, boolean saveCallStack, + boolean saveReturnValues) throws IOException, ProofInputException { if (tempNewOracleDirectory != null && tempNewOracleDirectory.isDirectory()) { // Create sub folder structure File oracleFile = new File(tempNewOracleDirectory, oraclePathInBaseDirFile); @@ -179,7 +176,7 @@ protected static void createOracleFile(IExecutionNode node, String oraclePath // Create oracle file ExecutionNodeWriter writer = new ExecutionNodeWriter(); writer.write(node, ExecutionNodeWriter.DEFAULT_ENCODING, oracleFile, saveVariables, - saveCallStack, saveReturnValues, saveConstraints); + saveCallStack, saveReturnValues, saveConstraints); // Print message to the user. printOracleDirectory(); } @@ -207,37 +204,37 @@ protected static void printOracleDirectory() { /** * Makes sure that the given nodes and their subtrees contains the same content. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? - * @param compareChildOrder Is the order of children relevant? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? + * @param compareChildOrder Is the order of children relevant? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { if (compareChildOrder) { // Order of children must be the same. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { // Order of children is not relevant. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); Set> currentVisitedNodes = new LinkedHashSet<>(); while (expectedExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); @@ -246,11 +243,11 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo fail("Node " + currentNext + " visited twice."); } assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } // Make sure that each current node was visited ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); if (!currentVisitedNodes.remove(currentNext)) { @@ -264,13 +261,13 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo /** * Searches the direct or indirect child in subtree of the node to search in. * - * @param toSearchIn The node to search in. + * @param toSearchIn The node to search in. * @param childToSearch The node to search. * @return The found node. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearchIn, - IExecutionNode childToSearch) throws ProofInputException { + IExecutionNode childToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(toSearchIn); assertNotNull(childToSearch); @@ -291,20 +288,20 @@ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearc } } assertNotNull(toSearchIn, "Direct or indirect Child " + childToSearch - + " is not contained in " + toSearchIn + "."); + + " is not contained in " + toSearchIn + "."); return toSearchIn; } /** * Searches the direct child. Nodes are equal if the name and the element type is equal. * - * @param parentToSearchIn The parent to search in its children. + * @param parentToSearchIn The parent to search in its children. * @param directChildToSearch The child to search. * @return The found child. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchDirectChildNode(IExecutionNode parentToSearchIn, - IExecutionNode directChildToSearch) throws ProofInputException { + IExecutionNode directChildToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(parentToSearchIn); assertNotNull(directChildToSearch); @@ -318,60 +315,60 @@ protected static IExecutionNode searchDirectChildNode(IExecutionNode paren if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) directChildToSearch) - .getAdditionalBranchLabel()) + ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) directChildToSearch) + .getAdditionalBranchLabel()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } else { if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } i++; } assertNotNull(result, - "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); + "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); return result; } /** * Makes sure that the given nodes contains the same content. Children are not compared. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareParent Compare also the parent node? - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareParent Compare also the parent node? + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertExecutionNode(IExecutionNode expected, IExecutionNode current, - boolean compareParent, boolean compareVariables, boolean compareCallStack, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareParent, boolean compareVariables, boolean compareCallStack, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { // Compare nodes assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); + "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); assertEquals(expected.isPathConditionChanged(), current.isPathConditionChanged()); if (!StringUtil.equalIgnoreWhiteSpace(expected.getFormatedPathCondition(), - current.getFormatedPathCondition())) { + current.getFormatedPathCondition())) { assertEquals(expected.getFormatedPathCondition(), current.getFormatedPathCondition()); } if (compareParent) { if (expected instanceof IExecutionBlockStartNode) { assertTrue(current instanceof IExecutionBlockStartNode); assertEquals(((IExecutionBlockStartNode) expected).isBlockOpened(), - ((IExecutionBlockStartNode) current).isBlockOpened()); + ((IExecutionBlockStartNode) current).isBlockOpened()); assertBlockCompletions((IExecutionBlockStartNode) expected, - (IExecutionBlockStartNode) current); + (IExecutionBlockStartNode) current); } assertCompletedBlocks(expected, current); assertOutgoingLinks(expected, current); @@ -380,177 +377,177 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution if (expected instanceof IExecutionBaseMethodReturn) { assertTrue(current instanceof IExecutionBaseMethodReturn); assertCallStateVariables((IExecutionBaseMethodReturn) expected, - (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); + (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); } if (expected instanceof IExecutionBranchCondition) { assertTrue(current instanceof IExecutionBranchCondition, - "Expected IExecutionBranchCondition but is " + current.getClass() + "."); + "Expected IExecutionBranchCondition but is " + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), - ((IExecutionBranchCondition) current).getFormatedBranchCondition()), - "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), + ((IExecutionBranchCondition) current).getFormatedBranchCondition()), + "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); assertEquals(((IExecutionBranchCondition) expected).isMergedBranchCondition(), - ((IExecutionBranchCondition) current).isMergedBranchCondition()); + ((IExecutionBranchCondition) current).isMergedBranchCondition()); assertEquals(((IExecutionBranchCondition) expected).isBranchConditionComputed(), - ((IExecutionBranchCondition) current).isBranchConditionComputed()); + ((IExecutionBranchCondition) current).isBranchConditionComputed()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), - "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), + "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStart) { assertTrue(current instanceof IExecutionStart, "Expected IExecutionStartNode but is " - + current.getClass() + "."); + + current.getClass() + "."); assertTerminations((IExecutionStart) expected, (IExecutionStart) current); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionTermination) { assertTrue(current instanceof IExecutionTermination, - "Expected IExecutionTermination but is " - + current.getClass() + "."); + "Expected IExecutionTermination but is " + + current.getClass() + "."); assertEquals(((IExecutionTermination) expected).getTerminationKind(), - ((IExecutionTermination) current).getTerminationKind()); + ((IExecutionTermination) current).getTerminationKind()); assertEquals(((IExecutionTermination) expected).isBranchVerified(), - ((IExecutionTermination) current).isBranchVerified()); + ((IExecutionTermination) current).isBranchVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionBranchStatement) { assertTrue(current instanceof IExecutionBranchStatement, - "Expected IExecutionBranchStatement but is " - + current.getClass() + "."); + "Expected IExecutionBranchStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopCondition) { assertTrue(current instanceof IExecutionLoopCondition, - "Expected IExecutionLoopCondition but is " - + current.getClass() + "."); + "Expected IExecutionLoopCondition but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopStatement) { assertTrue(current instanceof IExecutionLoopStatement, - "Expected IExecutionLoopStatement but is " - + current.getClass() + "."); + "Expected IExecutionLoopStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionMethodCall) { assertTrue(current instanceof IExecutionMethodCall, - "Expected IExecutionMethodCall but is " - + current.getClass() + "."); + "Expected IExecutionMethodCall but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); assertMethodReturns((IExecutionMethodCall) expected, (IExecutionMethodCall) current); } else if (expected instanceof IExecutionMethodReturn) { assertTrue(current instanceof IExecutionMethodReturn, - "Expected IExecutionMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), - ((IExecutionMethodReturn) current).getSignature()), - ((IExecutionMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), + ((IExecutionMethodReturn) current).getSignature()), + ((IExecutionMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionMethodReturn) current).getSignature()); if (compareReturnValues) { assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), - ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), - ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); assertEquals(((IExecutionMethodReturn) expected).isReturnValuesComputed(), - ((IExecutionMethodReturn) current).isReturnValuesComputed()); + ((IExecutionMethodReturn) current).isReturnValuesComputed()); } assertTrue( - StringUtil.equalIgnoreWhiteSpace( + StringUtil.equalIgnoreWhiteSpace( ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + + " does not match " + ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); if (compareReturnValues) { assertReturnValues(((IExecutionMethodReturn) expected).getReturnValues(), - ((IExecutionMethodReturn) current).getReturnValues()); + ((IExecutionMethodReturn) current).getReturnValues()); } } else if (expected instanceof IExecutionExceptionalMethodReturn) { assertTrue(current instanceof IExecutionExceptionalMethodReturn, - "Expected IExecutionExceptionalMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionExceptionalMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionExceptionalMethodReturn) expected).getSignature(), - ((IExecutionExceptionalMethodReturn) current).getSignature()), - ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionExceptionalMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionExceptionalMethodReturn) expected).getSignature(), + ((IExecutionExceptionalMethodReturn) current).getSignature()), + ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionExceptionalMethodReturn) current).getSignature()); assertTrue(StringUtil.equalIgnoreWhiteSpace( ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionExceptionalMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + ((IExecutionExceptionalMethodReturn) current) + + " does not match " + ((IExecutionExceptionalMethodReturn) current) .getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStatement) { assertTrue(current instanceof IExecutionStatement, - "Expected IExecutionStatement but is " - + current.getClass() + "."); + "Expected IExecutionStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionOperationContract) { assertTrue(current instanceof IExecutionOperationContract, - "Expected IExecutionOperationContract but is " - + current.getClass() + "."); + "Expected IExecutionOperationContract but is " + + current.getClass() + "."); assertEquals(((IExecutionOperationContract) expected).isPreconditionComplied(), - ((IExecutionOperationContract) current).isPreconditionComplied()); + ((IExecutionOperationContract) current).isPreconditionComplied()); assertEquals(((IExecutionOperationContract) expected).hasNotNullCheck(), - ((IExecutionOperationContract) current).hasNotNullCheck()); + ((IExecutionOperationContract) current).hasNotNullCheck()); assertEquals(((IExecutionOperationContract) expected).isNotNullCheckComplied(), - ((IExecutionOperationContract) current).isNotNullCheckComplied()); + ((IExecutionOperationContract) current).isNotNullCheckComplied()); assertEquals(((IExecutionOperationContract) expected).getFormatedResultTerm(), - ((IExecutionOperationContract) current).getFormatedResultTerm()); + ((IExecutionOperationContract) current).getFormatedResultTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedExceptionTerm(), - ((IExecutionOperationContract) current).getFormatedExceptionTerm()); + ((IExecutionOperationContract) current).getFormatedExceptionTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedSelfTerm(), - ((IExecutionOperationContract) current).getFormatedSelfTerm()); + ((IExecutionOperationContract) current).getFormatedSelfTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedContractParams(), - ((IExecutionOperationContract) current).getFormatedContractParams()); + ((IExecutionOperationContract) current).getFormatedContractParams()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopInvariant) { assertTrue(current instanceof IExecutionLoopInvariant, - "Expected IExecutionLoopInvariant but is " - + current.getClass() + "."); + "Expected IExecutionLoopInvariant but is " + + current.getClass() + "."); assertEquals(((IExecutionLoopInvariant) expected).isInitiallyValid(), - ((IExecutionLoopInvariant) current).isInitiallyValid()); + ((IExecutionLoopInvariant) current).isInitiallyValid()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionAuxiliaryContract) { assertTrue(current instanceof IExecutionAuxiliaryContract, - "Expected IExecutionBlockContract but is " - + current.getClass() + "."); + "Expected IExecutionBlockContract but is " + + current.getClass() + "."); assertEquals(((IExecutionAuxiliaryContract) expected).isPreconditionComplied(), - ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); + ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionJoin) { assertTrue(current instanceof IExecutionJoin, "Expected IExecutionJoin but is " - + current.getClass() + "."); + + current.getClass() + "."); assertEquals(((IExecutionJoin) expected).isWeakeningVerified(), - ((IExecutionJoin) current).isWeakeningVerified()); + ((IExecutionJoin) current).isWeakeningVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else { @@ -562,22 +559,22 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution IExecutionNode[] currentStack = current.getCallStack(); if (expectedStack != null) { assertNotNull(currentStack, - "Call stack of \"" + current + "\" should not be null."); + "Call stack of \"" + current + "\" should not be null."); assertEquals(expectedStack.length, currentStack.length, "Node: " + expected); for (int i = 0; i < expectedStack.length; i++) { assertExecutionNode(expectedStack[i], currentStack[i], false, false, false, - false, false); + false, false); } } else { assertTrue(currentStack == null || currentStack.length == 0, - "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) - + "\" but should be null or empty."); + "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) + + "\" but should be null or empty."); } } // Optionally compare parent if (compareParent) { assertExecutionNode(expected, current, false, compareVariables, compareCallStack, - compareReturnValues, compareConstraints); + compareReturnValues, compareConstraints); } } @@ -585,7 +582,7 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution * Compares the outgoing links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertOutgoingLinks(IExecutionNode expected, IExecutionNode current) @@ -594,9 +591,9 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getOutgoingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Outgoing links of \"" + current + "\" should not be null."); + "Outgoing links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Outgoing links: " + expected); + "Outgoing links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -604,15 +601,15 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Outgoing links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -620,7 +617,7 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution * Compares the incoming links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertIncomingLinks(IExecutionNode expected, IExecutionNode current) @@ -629,9 +626,9 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getIncomingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Incoming links of \"" + current + "\" should not be null."); + "Incoming links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Incoming links: " + expected); + "Incoming links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -639,15 +636,15 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Incoming links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -655,29 +652,29 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution * Compares the completed blocks. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertCompletedBlocks(IExecutionNode expected, - IExecutionNode current) throws ProofInputException { + IExecutionNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getCompletedBlocks(); ImmutableList> currentEntries = current.getCompletedBlocks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Completed blocks of \"" + current + "\" should not be null."); + "Completed blocks of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionBlockStartNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionBlockStartNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, false, false, - false, false, false); + false, false, false); String expectedCondition = - expected.getFormatedBlockCompletionCondition(expectedNext); + expected.getFormatedBlockCompletionCondition(expectedNext); String currentCondition = current.getFormatedBlockCompletionCondition(currentNext); if (!StringUtil.equalIgnoreWhiteSpace(expectedCondition, currentCondition)) { assertEquals(expectedCondition, currentCondition); @@ -687,8 +684,8 @@ protected static void assertCompletedBlocks(IExecutionNode expected, assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Completed block entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Completed block entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -696,33 +693,33 @@ protected static void assertCompletedBlocks(IExecutionNode expected, * Compares the block completions. * * @param expected The expected {@link IExecutionBlockStartNode}. - * @param current The current {@link IExecutionBlockStartNode}. + * @param current The current {@link IExecutionBlockStartNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertBlockCompletions(IExecutionBlockStartNode expected, - IExecutionBlockStartNode current) throws ProofInputException { + IExecutionBlockStartNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getBlockCompletions(); ImmutableList> currentEntries = current.getBlockCompletions(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Block completions of \"" + current + "\" should not be null."); + "Block completions of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Block completion entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Block completion entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -730,34 +727,34 @@ protected static void assertBlockCompletions(IExecutionBlockStartNode expecte * Compares the method returns. * * @param expected The expected {@link IExecutionMethodCall}. - * @param current The current {@link IExecutionMethodCall}. + * @param current The current {@link IExecutionMethodCall}. * @throws ProofInputException Occurred Exception. */ protected static void assertMethodReturns(IExecutionMethodCall expected, - IExecutionMethodCall current) throws ProofInputException { + IExecutionMethodCall current) throws ProofInputException { ImmutableList> expectedEntries = expected.getMethodReturns(); ImmutableList> currentEntries = current.getMethodReturns(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Method return of \"" + current + "\" should not be null."); + "Method return of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Method return entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Method return entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -765,7 +762,7 @@ protected static void assertMethodReturns(IExecutionMethodCall expected, * Compares the terminations. * * @param expected The expected {@link IExecutionStart}. - * @param current The current {@link IExecutionStart}. + * @param current The current {@link IExecutionStart}. * @throws ProofInputException Occurred Exception. */ protected static void assertTerminations(IExecutionStart expected, IExecutionStart current) @@ -776,22 +773,22 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta assertNotNull(currentEntries, "Termination of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Termination entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Termination entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -799,11 +796,11 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta * Makes sure that the given nodes contains the same {@link IExecutionMethodReturnValue}s. * * @param expected The expected {@link IExecutionMethodReturnValue}s. - * @param current The current {@link IExecutionMethodReturnValue}s. + * @param current The current {@link IExecutionMethodReturnValue}s. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, - IExecutionMethodReturnValue[] current) throws ProofInputException { + IExecutionMethodReturnValue[] current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertEquals(expected.length, current.length); @@ -816,36 +813,36 @@ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, * Makes sure that the given {@link IExecutionMethodReturnValue}s are the same. * * @param expected The expected {@link IExecutionMethodReturnValue}. - * @param current The current {@link IExecutionMethodReturnValue}. + * @param current The current {@link IExecutionMethodReturnValue}. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValue(IExecutionMethodReturnValue expected, - IExecutionMethodReturnValue current) throws ProofInputException { + IExecutionMethodReturnValue current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), - current.getReturnValueString()), - expected.getReturnValueString() + " does not match " + current.getReturnValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), + current.getReturnValueString()), + expected.getReturnValueString() + " does not match " + current.getReturnValueString()); assertEquals(expected.hasCondition(), current.hasCondition()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); } /** * Makes sure that the given nodes contains the same {@link IExecutionNode}s. * - * @param expected The expected node. - * @param current The current node. + * @param expected The expected node. + * @param current The current node. * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionNode expected, IExecutionNode current, - boolean compareConstraints) throws ProofInputException { + boolean compareConstraints) throws ProofInputException { if (compareConstraints) { assertNotNull(expected); assertNotNull(current); @@ -859,26 +856,26 @@ protected static void assertConstraints(IExecutionNode expected, IExecutionNo * Makes sure that the given constraints are the same. * * @param expected The expected constraints. - * @param current The current constraints. + * @param current The current constraints. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionConstraint[] expected, - IExecutionConstraint[] current) throws ProofInputException { + IExecutionConstraint[] current) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionConstraint expectedVariable : expected) { // Find current variable with same name IExecutionConstraint currentVariable = CollectionUtil.searchAndRemove( - availableCurrentVariables, element -> { - try { - return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); - } catch (ProofInputException e) { - throw new RuntimeException(e); - } - }); + availableCurrentVariables, element -> { + try { + return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), + element.getName()); + } catch (ProofInputException e) { + throw new RuntimeException(e); + } + }); assertNotNull(currentVariable); // Compare variables assertConstraint(expectedVariable, currentVariable); @@ -890,11 +887,11 @@ protected static void assertConstraints(IExecutionConstraint[] expected, * Makes sure that the given constraints are the same. * * @param expected The expected constraint. - * @param current The current constraint. + * @param current The current constraint. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraint(IExecutionConstraint expected, - IExecutionConstraint current) throws ProofInputException { + IExecutionConstraint current) throws ProofInputException { if (expected != null) { assertNotNull(current); if (!StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName())) { @@ -909,15 +906,15 @@ protected static void assertConstraint(IExecutionConstraint expected, * Makes sure that the given nodes contains the same {@link IExecutionVariable}s of the call * state. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertCallStateVariables(IExecutionBaseMethodReturn expected, - IExecutionBaseMethodReturn current, boolean compareVariables, - boolean compareConstraints) throws ProofInputException { + IExecutionBaseMethodReturn current, boolean compareVariables, + boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -930,14 +927,14 @@ protected static void assertCallStateVariables(IExecutionBaseMethodReturn exp /** * Makes sure that the given nodes contains the same {@link IExecutionVariable}s. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -950,27 +947,27 @@ protected static void assertVariables(IExecutionNode expected, IExecutionNode /** * Makes sure that the given variables are the same. * - * @param expected The expected variables. - * @param current The current variables. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variables. + * @param current The current variables. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionVariable[] expected, - IExecutionVariable[] current, boolean compareParent, boolean compareChildren, - boolean compareConstraints) throws ProofInputException { + IExecutionVariable[] current, boolean compareParent, boolean compareChildren, + boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionVariable expectedVariable : expected) { // Find current variable with same name IExecutionVariable currentVariable = CollectionUtil .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); + element.getName()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -978,7 +975,7 @@ protected static void assertVariables(IExecutionVariable[] expected, assertNotNull(currentVariable); // Compare variables assertVariable(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -986,15 +983,15 @@ protected static void assertVariables(IExecutionVariable[] expected, /** * Makes sure that the given variables are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariable(IExecutionVariable expected, IExecutionVariable current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); @@ -1005,7 +1002,7 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari // Compare parent if (compareParent) { assertValue(expected.getParentValue(), current.getParentValue(), false, false, - false); + false); } // Compare children if (compareChildren) { @@ -1021,15 +1018,15 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari /** * Makes sure that the given values are the same. * - * @param expected The expected values. - * @param current The current values. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected values. + * @param current The current values. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order @@ -1040,10 +1037,10 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()) + element.getName()) && StringUtil.equalIgnoreWhiteSpace( - expectedVariable.getConditionString(), - element.getConditionString()); + expectedVariable.getConditionString(), + element.getConditionString()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -1051,7 +1048,7 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] assertNotNull(currentVariable); // Compare variables assertValue(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -1059,43 +1056,43 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] /** * Makes sure that the given values are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValue(IExecutionValue expected, IExecutionValue current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); // Compare variable assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertEquals(expected.getTypeString(), current.getTypeString()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), - current.getValueString()), - expected.getValueString() + " does not match " + current.getValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), + current.getValueString()), + expected.getValueString() + " does not match " + current.getValueString()); assertEquals(expected.isValueAnObject(), current.isValueAnObject()); assertEquals(expected.isValueUnknown(), current.isValueUnknown()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); // Compare parent if (compareParent) { assertVariable(expected.getVariable(), current.getVariable(), false, false, - compareConstraints); + compareConstraints); } // Compare children if (compareChildren) { IExecutionVariable[] expectedChildVariables = expected.getChildVariables(); IExecutionVariable[] currentChildVariables = current.getChildVariables(); assertVariables(expectedChildVariables, currentChildVariables, compareParent, - compareChildren, compareConstraints); + compareChildren, compareConstraints); } // Compare constraints if (compareConstraints) { @@ -1112,27 +1109,27 @@ protected static void assertValue(IExecutionValue expected, IExecutionValue curr * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturn(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); @@ -1142,8 +1139,9 @@ protected static void stepReturn(DefaultUserInterfaceControl ui, // Update symbolic execution tree builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -1154,27 +1152,27 @@ protected static void stepReturn(DefaultUserInterfaceControl ui, * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); stopCondition.addChildren(lineBreakpoints); proof.getSettings().getStrategySettings() @@ -1185,8 +1183,9 @@ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, // Update symbolic execution tree builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -1196,27 +1195,27 @@ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, * Executes a "step over" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepOver(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepOverSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); @@ -1226,8 +1225,9 @@ protected static void stepOver(DefaultUserInterfaceControl ui, // Update symbolic execution tree builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -1237,28 +1237,28 @@ protected static void stepOver(DefaultUserInterfaceControl ui, * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. * @return The found {@link SymbolicExecutionCompletions}. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof @@ -1268,8 +1268,9 @@ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceContr // Update symbolic execution tree SymbolicExecutionCompletions completions = builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); return completions; } catch (InterruptedException e) { throw new RuntimeException(e); @@ -1280,24 +1281,24 @@ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceContr * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void resume(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof @@ -1316,20 +1317,20 @@ protected static void resume(DefaultUserInterfaceControl ui, /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, File baseDir) + String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { if (CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { createOracleFile(builder.getStartNode(), oraclePathInBaseDirFile, false, false, false, - false); + false); } else { // Read oracle file File oracleFile = new File(baseDir, oraclePathInBaseDirFile); @@ -1338,41 +1339,41 @@ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builde assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, builder.getStartNode(), false, false, false, false, - false); + false); } } /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, - File baseDir) + String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, + File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { assertSetTreeAfterStep(builder, - oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); + oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); } /** * Searches a {@link IProgramMethod} in the given {@link Services}. * - * @param services The {@link Services} to search in. + * @param services The {@link Services} to search in. * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. + * @param methodFullName The method name to search. * @return The first found {@link IProgramMethod} in the type. */ public static IProgramMethod searchProgramMethod(Services services, String containerTypeName, - final String methodFullName) { + final String methodFullName) { return HelperClassForTests.searchProgramMethod(services, containerTypeName, methodFullName); } @@ -1381,29 +1382,29 @@ public static IProgramMethod searchProgramMethod(Services services, String conta * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param baseContractName The name of the contract. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param baseContractName The name of the contract. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String baseContractName, @@ -1417,26 +1418,26 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, - null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, + null, null, null, true); setupTacletOptions(environment); // Start proof final Contract contract = environment.getServices().getSpecificationRepository() .getContractByName(baseContractName); assertTrue(contract instanceof FunctionalOperationContract); ProofOblInput input = new FunctionalOperationContractPO(environment.getInitConfig(), - (FunctionalOperationContract) contract, true, true); + (FunctionalOperationContract) contract, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1448,30 +1449,30 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1485,25 +1486,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodPO(environment.getInitConfig(), pm.getFullName(), pm, - precondition, true, true); + precondition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1526,26 +1527,26 @@ private static void setupTacletOptions(KeYEnvironment env) { * Creates a {@link SymbolicExecutionEnvironment} which consists of loading a proof file to load * and creation with configuration of {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param proofPathInBaseDir The path to the proof file inside the base directory. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofPathInBaseDir The path to the proof file inside the base directory. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. */ @@ -1562,20 +1563,20 @@ protected static SymbolicExecutionEnvironment creat assertTrue(proofFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, - null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, + null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); setupTacletOptions(environment); Proof proof = environment.getLoadedProof(); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1587,32 +1588,32 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param startPosition The start position. - * @param endPosition The end position. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param startPosition The start position. + * @param endPosition The end position. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1627,25 +1628,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodSubsetPO(environment.getInitConfig(), methodFullName, - pm, precondition, startPosition, endPosition, true, true); + pm, precondition, startPosition, endPosition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1670,7 +1671,7 @@ protected String getTryContent(Proof proof) { JavaProgramElement updateContent = updateApplication.subs().get(1).javaBlock().program(); assertTrue(updateContent instanceof StatementBlock); ImmutableArray updateContentBody = - ((StatementBlock) updateContent).getBody(); + ((StatementBlock) updateContent).getBody(); assertEquals(2, updateContentBody.size()); assertTrue(updateContentBody.get(1) instanceof Try); Try tryStatement = (Try) updateContentBody.get(1); @@ -1681,39 +1682,39 @@ protected String getTryContent(Proof proof) { /** * Makes sure that the save and loading process works. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. * @param oraclePathInBaseDirFile The oracle path. - * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof - * to save/load. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof + * to save/load. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, - String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) + String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) throws IOException, ProofInputException, ParserConfigurationException, SAXException, ProblemLoaderException { File javaFile = new File(baseDir, javaPathInBaseDir); assertTrue(javaFile.exists()); File tempFile = - File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); + File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); KeYEnvironment reloadedEnv = null; SymbolicExecutionTreeBuilder reloadedBuilder = null; try { ProofSaver saver = new ProofSaver(env.getProof(), tempFile.getAbsolutePath(), - KeYConstants.INTERNAL_VERSION); + KeYConstants.INTERNAL_VERSION); assertNull(saver.save()); // Load proof from saved *.proof file reloadedEnv = KeYEnvironment.load(SymbolicExecutionJavaProfile.getDefaultInstance(), - tempFile, null, null, null, true); + tempFile, null, null, null, true); Proof reloadedProof = reloadedEnv.getLoadedProof(); assertNotSame(env.getProof(), reloadedProof); // Recreate symbolic execution tree reloadedBuilder = - new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); + new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); SymbolicExecutionUtil.initializeStrategy(reloadedBuilder); reloadedBuilder.analyse(); assertSetTreeAfterStep(reloadedBuilder, oraclePathInBaseDirFile, baseDir); @@ -1742,59 +1743,59 @@ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? * @param maximalNumberOfExecutedSetNodesPerRun The number of executed set nodes per auto mode - * run. The whole test is executed for each defined value. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. - * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * run. The whole test is executed for each defined value. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. + * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containerTypeName, - String methodFullName, String precondition, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String methodFullName, String precondition, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { assertNotNull(maximalNumberOfExecutedSetNodesPerRun); for (int j : maximalNumberOfExecutedSetNodesPerRun) { SymbolicExecutionEnvironment env = doSETTest(baseDir, - javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, j, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, j, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } } @@ -1803,57 +1804,57 @@ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containe * Executes method doTest * and disposes the created {@link SymbolicExecutionEnvironment}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, - String containerTypeName, String methodFullName, String precondition, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String containerTypeName, String methodFullName, String precondition, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, simplifyConditions); + doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } @@ -1870,47 +1871,47 @@ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, - includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, false, true); + doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, + includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, false, true); if (env != null) { env.dispose(); } @@ -1929,47 +1930,47 @@ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String proofFilePathInBaseDir, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String proofFilePathInBaseDir, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { boolean originalOneStepSimplification = isOneStepSimplificationEnabled(null); SymbolicExecutionEnvironment env; @@ -1980,26 +1981,26 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } // Make sure that the correct taclet options are defined. setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution env = createSymbolicExecutionEnvironment(baseDir, proofFilePathInBaseDir, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, - simplifyConditions); + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, + simplifyConditions); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); return env; } finally { // Restore original options @@ -2020,49 +2021,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String containerTypeName, final String methodFullName, - String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, - boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String javaPathInBaseDir, String containerTypeName, final String methodFullName, + String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, + boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; @@ -2076,23 +2077,23 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = setDefaultTacletOptions(baseDir, javaPathInBaseDir, - containerTypeName, methodFullName); + containerTypeName, methodFullName); setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, precondition, mergeBranchConditions, useOperationContracts, - useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, - aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, precondition, mergeBranchConditions, useOperationContracts, + useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, + aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore original options @@ -2114,49 +2115,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param baseContractName The name of the contract. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseContractName The name of the contract. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; try { @@ -2167,22 +2168,22 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = - setDefaultTacletOptions(javaPathInBaseDir, baseContractName); + setDefaultTacletOptions(javaPathInBaseDir, baseContractName); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, - useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - truthValueEvaluationEnabled, simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, + useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + truthValueEvaluationEnabled, simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore taclet options @@ -2194,15 +2195,15 @@ protected SymbolicExecutionEnvironment doSETTest(Fi * Internal test method */ private void internalDoSETTest(File oracleFile, - SymbolicExecutionEnvironment env, - String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues) + SymbolicExecutionEnvironment env, + String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); + new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); env.getProof().getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); int nodeCount; @@ -2218,11 +2219,12 @@ private void internalDoSETTest(File oracleFile, // Update symbolic execution tree env.getBuilder().analyse(); // Make sure that not to many set nodes are executed - Map executedSetNodesPerGoal = stopCondition.getExectuedSetNodesPerGoal(); + Map executedSetNodesPerGoal = + stopCondition.getExectuedSetNodesPerGoal(); for (Integer value : executedSetNodesPerGoal.values()) { assertNotNull(value); assertTrue(value <= maximalNumberOfExecutedSetNodes, - value + " is not less equal to " + maximalNumberOfExecutedSetNodes); + value + " is not less equal to " + maximalNumberOfExecutedSetNodes); } } catch (InterruptedException e) { throw new RuntimeException(e); @@ -2230,36 +2232,36 @@ private void internalDoSETTest(File oracleFile, } while (stopCondition.wasSetNodeExecuted() && nodeCount != env.getProof().countNodes()); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); } /** * Ensures that the default taclet options are defined. * * @param javaPathInBaseDir The path in the base directory to the java file. - * @param baseContractName The name of the contract to prove. + * @param baseContractName The name of the contract to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(String javaPathInBaseDir, - String baseContractName) + String baseContractName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, - baseContractName, - false, false, false, - false, false, false, - false, false, false, - false, false); + createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, + baseContractName, + false, false, false, + false, false, false, + false, false, false, + false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2268,26 +2270,26 @@ public static Map setDefaultTacletOptions(String javaPathInBaseD /** * Ensures that the default taclet options are defined. * - * @param baseDir The base directory which contains the java file. + * @param baseDir The base directory which contains the java file. * @param javaPathInBaseDir The path in the base directory to the java file. * @param containerTypeName name of the type where the method is implemented/declared - * @param methodFullName The method to prove. + * @param methodFullName The method to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(File baseDir, - String javaPathInBaseDir, - String containerTypeName, - String methodFullName) + String javaPathInBaseDir, + String containerTypeName, + String methodFullName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, - null, false, false, false, - false, false, false, false, - false, false, false); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, + null, false, false, false, + false, false, false, false, + false, false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2296,19 +2298,19 @@ public static Map setDefaultTacletOptions(File baseDir, /** * Ensures that the default taclet options are defined. * - * @param javaFile The java file to load. + * @param javaFile The java file to load. * @param containerTypeName The type name which provides the target. - * @param targetName The target to proof. + * @param targetName The target to proof. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ @SuppressWarnings("unused") public static Map setDefaultTacletOptionsForTarget(File javaFile, - String containerTypeName, final String targetName) + String containerTypeName, final String targetName) throws ProblemLoaderException, ProofInputException { return HelperClassForTests.setDefaultTacletOptionsForTarget(javaFile, containerTypeName, - targetName); + targetName); } /** @@ -2342,14 +2344,14 @@ public static void restoreTacletOptions(Map options) { protected ITermProgramVariableCollectorFactory createNewProgramVariableCollectorFactory( final SymbolicExecutionBreakpointStopCondition breakpointParentStopCondition) { return services -> new TermProgramVariableCollectorKeepUpdatesForBreakpointconditions( - services, breakpointParentStopCondition); + services, breakpointParentStopCondition); } /** * Makes sure that two {@link Term}s are equal. * * @param expected The expected {@link Term}. - * @param actual The actual {@link Term}. + * @param actual The actual {@link Term}. */ protected void assertTerm(Term expected, Term actual) { if (expected != null) { @@ -2369,7 +2371,7 @@ protected void assertTerm(Term expected, Term actual) { * Checks if one-step simplification is enabled in the given {@link Proof}. * * @param proof The {@link Proof} to read from or {@code null} to return the general settings - * value. + * value. * @return {@code true} one step simplification is enabled, {@code false} if disabled. */ public static boolean isOneStepSimplificationEnabled(Proof proof) { @@ -2379,9 +2381,9 @@ public static boolean isOneStepSimplificationEnabled(Proof proof) { /** * Defines if one-step simplification is enabled in general and within the {@link Proof}. * - * @param proof The optional {@link Proof}. + * @param proof The optional {@link Proof}. * @param enabled {@code true} use one-step simplification, {@code false} do not use one-step - * simplification. + * simplification. */ public static void setOneStepSimplificationEnabled(Proof proof, boolean enabled) { HelperClassForTests.setOneStepSimplificationEnabled(proof, enabled); diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java index 29a34424d09..e466b3e4876 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java @@ -564,7 +564,8 @@ public void startAndWaitForAutoMode(Proof proof) throws InterruptedException { * {@inheritDoc} */ @Override - public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException { + public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) + throws InterruptedException { startAutoMode(proof, goals); waitWhileAutoMode(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java index 48dda5aa1f3..00a423b76c5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java @@ -3,6 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.control; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + import de.uka.ilkd.key.logic.PosInOccurrence; import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; @@ -16,10 +19,8 @@ import de.uka.ilkd.key.prover.impl.ApplyStrategy; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; import de.uka.ilkd.key.util.ProofStarter; -import org.key_project.util.collection.ImmutableList; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; +import org.key_project.util.collection.ImmutableList; /** * The default implementation of {@link ProofControl}. @@ -45,12 +46,12 @@ public class DefaultProofControl extends AbstractProofControl { /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. + * to all started {@link ApplyStrategy} instances. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener) { + DefaultUserInterfaceControl defaultProverTaskListener) { super(defaultProverTaskListener); this.ui = ui; } @@ -58,21 +59,21 @@ public DefaultProofControl(UserInterfaceControl ui, /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * to all started {@link ApplyStrategy} instances. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener, - RuleCompletionHandler ruleCompletionHandler) { + DefaultUserInterfaceControl defaultProverTaskListener, + RuleCompletionHandler ruleCompletionHandler) { super(defaultProverTaskListener, ruleCompletionHandler); this.ui = ui; } @Override public synchronized void startAutoMode(Proof proof, ImmutableList goals, - ProverTaskListener ptl) { + ProverTaskListener ptl) { if (!isInAutoMode()) { autoModeThread = new AutoModeThread(proof, goals, ptl); autoModeThread.start(); @@ -121,7 +122,7 @@ public void run() { fireAutoModeStarted(new ProofEvent(proof)); ProofStarter starter = ptl != null ? new ProofStarter( - new CompositePTListener(getDefaultProverTaskListener(), ptl), false) + new CompositePTListener(getDefaultProverTaskListener(), ptl), false) : new ProofStarter(getDefaultProverTaskListener(), false); starter.init(proof); if (goals != null) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java index dc2936d64e7..c791034caa9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java @@ -3,6 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.control; +import java.io.File; +import java.util.*; +import java.util.function.Consumer; + import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.abstraction.KeYJavaType; @@ -21,11 +25,8 @@ import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.util.KeYTypeUtil; import de.uka.ilkd.key.util.Pair; -import org.key_project.util.collection.ImmutableSet; -import java.io.File; -import java.util.*; -import java.util.function.Consumer; +import org.key_project.util.collection.ImmutableSet; /** * Instances of this class are used to collect and access all relevant information for verification @@ -67,7 +68,7 @@ public class KeYEnvironment { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig) { @@ -77,11 +78,11 @@ public KeYEnvironment(U ui, InitConfig initConfig) { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig, Proof loadedProof, - Pair proofScript, ReplayResult replayResult) { + Pair proofScript, ReplayResult replayResult) { this.ui = ui; this.initConfig = initConfig; this.loadedProof = loadedProof; @@ -180,15 +181,15 @@ public Proof createProof(ProofOblInput input) throws ProofInputException { * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. + * @param location The location to load. + * @param classPaths The class path entries to use. * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param includes Optional includes to consider. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes) + List classPaths, File bootClassPath, List includes) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, false); } @@ -197,103 +198,103 @@ public static KeYEnvironment load(File location, * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes, - RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, null, - ruleCompletionHandler, false); + ruleCompletionHandler, false); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as - * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file - * will be used for new proofs. + * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file + * will be used for new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, null, null, - forceNewProfileOfNewProofs); + forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, poPropertiesToForce, - ruleCompletionHandler, - null, forceNewProfileOfNewProofs); + ruleCompletionHandler, + null, forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. - * @param callbackProofLoaded An optional callback (called when the proof is loaded, before - * replay) + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param callbackProofLoaded An optional callback (called when the proof is loaded, before + * replay) * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - Consumer callbackProofLoaded, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + Consumer callbackProofLoaded, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { DefaultUserInterfaceControl ui = new DefaultUserInterfaceControl(ruleCompletionHandler); AbstractProblemLoader loader = ui.load(profile, location, classPaths, bootClassPath, - includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); + includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); InitConfig initConfig = loader.getInitConfig(); return new KeYEnvironment<>(ui, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); } public static KeYEnvironment load(File keyFile) @@ -335,9 +336,11 @@ public List getAvailableContracts() { Set kjts = getJavaInfo().getAllKeYJavaTypes(); for (KeYJavaType type : kjts) { if (!KeYTypeUtil.isLibraryClass(type)) { - ImmutableSet targets = getSpecificationRepository().getContractTargets(type); + ImmutableSet targets = + getSpecificationRepository().getContractTargets(type); for (IObserverFunction target : targets) { - ImmutableSet contracts = getSpecificationRepository().getContracts(type, target); + ImmutableSet contracts = + getSpecificationRepository().getContracts(type, target); for (Contract contract : contracts) { proofContracts.add(contract); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java index f30b7bb97d1..3b5971cbb72 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java @@ -123,7 +123,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * * @param proof The {@link Proof} to start auto mode of. */ - default void startAutoMode(Proof proof) { startAutoMode(proof, proof.openEnabledGoals());} + default void startAutoMode(Proof proof) { startAutoMode(proof, proof.openEnabledGoals()); } /** * Starts the auto mode for the given {@link Proof} and the given {@link Goal}s. @@ -158,7 +158,8 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * @param proof The {@link Proof} to start auto mode and to wait for. * @param goals The {@link Goal}s to close. */ - void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException; + void startAndWaitForAutoMode(Proof proof, ImmutableList goals) + throws InterruptedException; /** * Starts the auto mode for the given proof which must be contained in this user interface and diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java index 29b9579f640..476d4ef1cb9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java @@ -18,7 +18,8 @@ public class ProofMacroFacade { private static ProofMacroFacade INSTANCE; public static ProofMacroFacade instance() { - if (INSTANCE == null) INSTANCE = new ProofMacroFacade(); + if (INSTANCE == null) + INSTANCE = new ProofMacroFacade(); return INSTANCE; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java index ebe8d366f00..962228f3ca8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.macros; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java index 44a26161832..8414e89e769 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.macros.scripts; -import de.uka.ilkd.key.smt.IllegalNumberException; import java.util.Collection; import java.util.HashMap; @@ -25,7 +24,8 @@ public ProofScriptCommandFacade() { } public static ProofScriptCommandFacade instance() { - if(INSTANCE == null) INSTANCE = new ProofScriptCommandFacade(); + if (INSTANCE == null) + INSTANCE = new ProofScriptCommandFacade(); return INSTANCE; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java index 6198a8b88d9..67415ae80fd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java @@ -774,7 +774,7 @@ public List getAvailableRules() { if (just == null) { continue; // do not break system because of this } - s.add(app.taclet()); //TODO not good + s.add(app.taclet()); // TODO not good } return s; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 95ba46fe7be..9676dc91980 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.proof; +import java.util.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -24,15 +25,13 @@ import de.uka.ilkd.key.rule.RuleApp; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.util.Pair; + import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.collection.ImmutableSet; import org.key_project.util.lookup.Lookup; -import java.util.*; -import java.util.stream.Stream; - import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -128,7 +127,7 @@ public class Node implements Iterable { * taclet with an addrule section on this node, then these taclets are stored in this list */ private ImmutableSet localIntroducedRules = - DefaultImmutableSet.nil(); + DefaultImmutableSet.nil(); /** * Holds the undo methods for the information added by rules to the {@code Goal.strategyInfos}. @@ -459,7 +458,7 @@ List getLeaves() { /** * @return an iterator for the leaves of the subtree below this node. The computation is called - * at every call! + * at every call! */ public Iterator leavesIterator() { return new NodeIterator(getLeaves().iterator()); @@ -504,7 +503,7 @@ public Node child(int i) { /** * @param child a child of this node. * @return the number of the node child, if it is a child of this node (starting - * with 0), -1 otherwise + * with 0), -1 otherwise */ public int getChildNr(Node child) { int res = 0; @@ -544,16 +543,16 @@ public StringBuffer getUniqueTacletId() { * Helper for {@link #toString()} * * @param prefix needed to keep track if a line has to be printed - * @param tree the tree representation we want to add this subtree " @param preEnumeration the - * enumeration of the parent without the last number + * @param tree the tree representation we want to add this subtree " @param preEnumeration the + * enumeration of the parent without the last number * @param postNr the last number of the parents enumeration - * @param maxNr the number of nodes at this level - * @param ownNr the place of this node at this level + * @param maxNr the number of nodes at this level + * @param ownNr the place of this node at this level * @return the string representation of this node. */ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumeration, - int postNr, int maxNr, int ownNr) { + int postNr, int maxNr, int ownNr) { Iterator childrenIt = childrenIterator(); // Some constants String frontIndent = (maxNr > 1 ? " " : ""); @@ -604,7 +603,7 @@ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumer while (childrenIt.hasNext()) { childId++; childrenIt.next().toString(prefix, tree, newEnumeration, newPostNr, children.size(), - childId); + childId); } return tree; @@ -661,7 +660,7 @@ public String name() { * this node. * * @return true iff the parent of this node has this node as child and this condition holds also - * for the own children. + * for the own children. */ public boolean sanityCheckDoubleLinks() { if (!root()) { @@ -788,7 +787,7 @@ public Iterator iterator() { * Retrieves a user-defined data. * * @param service the class for which the data were registered - * @param any class + * @param any class * @return null or the previous data * @see #register(Object, Class) */ @@ -806,7 +805,7 @@ public T lookup(Class service) { /** * Register a user-defined data in this node info. * - * @param obj an object to be registered + * @param obj an object to be registered * @param service the key under it should be registered * @param */ @@ -817,9 +816,9 @@ public void register(T obj, Class service) { /** * Remove a previous registered user-defined data. * - * @param obj registered object + * @param obj registered object * @param service the key under which the data was registered - * @param arbitray object + * @param arbitray object */ public void deregister(T obj, Class service) { if (userData != null) { diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java index 21f2fbc3674..04333491df3 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java @@ -3,28 +3,31 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.speclang.njml; +import java.io.File; +import java.util.stream.Stream; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.init.ProofInputException; import de.uka.ilkd.key.proof.io.ProblemLoaderException; import de.uka.ilkd.key.util.HelperClassForTests; + import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.util.stream.Stream; - public class ContractLoadingTests { public static final File EXAMPLES_DIR = new File("../key.ui/examples/"); static Stream files() { return Stream.of( - new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"), - new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"), - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"), - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java") - ).map(Arguments::of); + new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java")) + .map(Arguments::of); } @ParameterizedTest @@ -33,9 +36,11 @@ void issues1717() throws ProblemLoaderException, ProofInputException { File javaFile = new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1717/UnderscoreZero.java"); Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); - var proof = file.startProof(file.getProofContracts().get(0)); + + KeYEnvironment env = KeYEnvironment.load(javaFile); + Assertions.assertFalse(env.getAvailableContracts().isEmpty()); + var proof = + env.createProof(env.getAvailableContracts().get(0).createProofObl(env.getInitConfig())); Assertions.assertNotNull(proof); } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java index 85a85b65df1..3d9c18f83f7 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java @@ -1,10 +1,8 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -14,9 +12,15 @@ import java.util.Enumeration; import java.util.List; import java.util.Properties; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * This class wraps a {@link java.io.File} and has a special {@link #toString()} method only using the + * This class wraps a {@link java.io.File} and has a special {@link #toString()} method only using + * the * short file name w/o path. *

    * Used for displaying files in the examples list w/o prefix @@ -139,12 +143,12 @@ public String toString() { public void addToTreeModel(DefaultTreeModel model) { DefaultMutableTreeNode node = - findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); + findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); node.add(new DefaultMutableTreeNode(this)); } private DefaultMutableTreeNode findChild(DefaultMutableTreeNode root, String[] path, - int from) { + int from) { if (from == path.length) { return root; } @@ -166,7 +170,7 @@ public boolean hasProof() { } private static StringBuilder extractDescription(File file, StringBuilder sb, - Properties properties) { + Properties properties) { try (BufferedReader r = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) { String line; boolean emptyLineSeen = false; @@ -193,4 +197,4 @@ private static StringBuilder extractDescription(File file, StringBuilder sb, } return sb; } -} \ No newline at end of file +} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java index a80815bbe03..24c539bf86f 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java @@ -3,6 +3,12 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; +import javax.swing.*; + import de.uka.ilkd.key.control.InteractionListener; import de.uka.ilkd.key.core.InterruptListener; import de.uka.ilkd.key.core.KeYMediator; @@ -16,15 +22,10 @@ import de.uka.ilkd.key.prover.ProverTaskListener; import de.uka.ilkd.key.prover.TaskStartedInfo; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.swing.*; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; - /** * The Class ProofMacroWorker is a swing worker for the application of proof macros. *

    @@ -40,7 +41,7 @@ public class ProofMacroWorker extends SwingWorker * goals under the current pio, selection remains where it was. */ private static final boolean SELECT_GOAL_AFTER_MACRO = - Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); + Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); /** * The {@link Node} to start macro at. @@ -75,13 +76,13 @@ public class ProofMacroWorker extends SwingWorker /** * Instantiates a new proof macro worker. * - * @param node the {@link Node} to start macro at. - * @param macro the macro, not null + * @param node the {@link Node} to start macro at. + * @param macro the macro, not null * @param mediator the mediator, not null * @param posInOcc the position, possibly null */ public ProofMacroWorker(Node node, ProofMacro macro, KeYMediator mediator, - PosInOccurrence posInOcc) { + PosInOccurrence posInOcc) { assert macro != null; assert mediator != null; this.node = node; @@ -98,7 +99,7 @@ protected ProofMacroFinishedInfo doInBackground() { Proof selectedProof = node.proof(); info = ProofMacroFinishedInfo.getDefaultInfo(macro, selectedProof); ptl.taskStarted( - new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); + new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); try { synchronized (macro) { info = macro.applyTo(mediator.getUI(), node, posInOcc, ptl); @@ -144,7 +145,7 @@ protected void done() { } protected void emitProofMacroFinished(Node node, ProofMacro macro, PosInOccurrence posInOcc, - ProofMacroFinishedInfo info) { + ProofMacroFinishedInfo info) { interactionListeners.forEach((l) -> l.runMacro(node, macro, posInOcc, info)); } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java index 2b8a53215d5..d3bfa1a769e 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java @@ -24,16 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.awt.event.ActionEvent; -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - /** * This class provides an action for KeY UI which runs a set of specified proof files automatically. * The intent of this class is to have a massive test feature for the quality assurance of the KeY @@ -83,7 +73,7 @@ public class RunAllProofsAction extends MainWindowAction { @NonNull private List loadFiles() throws IOException { LOGGER.info("Use 'export {}=<...>' to set the input file for {}.", ENV_VARIABLE, - getClass().getSimpleName()); + getClass().getSimpleName()); InputStream stream; if (RUN_ALL_PROOFS_UI == null) { @@ -97,7 +87,7 @@ private List loadFiles() throws IOException { } try (BufferedReader in = - new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { return in.lines().filter(it -> !it.startsWith("#") && !it.trim().isEmpty()) .map(it -> (it.startsWith("/") ? new File(it) : new File(exampleDir, it)) .getAbsoluteFile()) @@ -120,7 +110,7 @@ public RunAllProofsAction(MainWindow mainWindow) { setName("Run all proofs"); setTooltip( - "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); + "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); } @Override @@ -136,7 +126,7 @@ public void actionPerformed(ActionEvent e) { ui.reportStatus(this, "Run: " + absFile); LOGGER.info("Run: {}", absFile); ProblemLoader problemLoader = - ui.getProblemLoader(absFile, null, null, null, getMediator()); + ui.getProblemLoader(absFile, null, null, null, getMediator()); problemLoader.runSynchronously(); LOGGER.info("Loaded: {}", absFile); diff --git a/keyext.api.doc/src/main/java/DocGen.java b/keyext.api.doc/src/main/java/DocGen.java index 36aed393607..8ab51393898 100644 --- a/keyext.api.doc/src/main/java/DocGen.java +++ b/keyext.api.doc/src/main/java/DocGen.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Comparator; @@ -47,9 +50,9 @@ private void printHeader() { } private void endpoints(Metamodel.Endpoint endpoint) { - //out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); - //out.println(getJavaDoc(typeDeclaration)); - //out.println("\n"); + // out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); + // out.println(getJavaDoc(typeDeclaration)); + // out.println("\n"); var direction = ""; if (endpoint instanceof Metamodel.ServerRequest sr) @@ -91,9 +94,9 @@ private void printType(Metamodel.Type type) { } ``` """.formatted(type.name(), - ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) - .map(it -> "\t%s : %s".formatted(it.name(), it.type())) - .collect(Collectors.joining("\n")))); + ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) + .map(it -> "\t%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining("\n")))); } if (type instanceof Metamodel.EnumType et) { @@ -101,89 +104,87 @@ private void printType(Metamodel.Type type) { ``` enum %s { %s } ``` - """.formatted(type.name(), String.join(", ", et.values()) - )); + """.formatted(type.name(), String.join(", ", et.values()))); out.format(type.documentation()); } out.format(type.documentation()); out.println(); } - /* - private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ - var annotationExpr = m.getAnnotationByName("JsonNotification").or( - () -> m.getAnnotationByName("JsonRequest")) - .orElseThrow(); - - var segment = getJsonSegment(td) + "/"; - String name = ""; - - if (annotationExpr.isMarkerAnnotationExpr()) { - name = m.getNameAsString(); - } else if (annotationExpr.isSingleMemberAnnotationExpr()) { - var sma = annotationExpr.asSingleMemberAnnotationExpr(); - name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); - } else { - var ne = annotationExpr.asNormalAnnotationExpr(); - for (MemberValuePair pair : ne.getPairs()) { - switch (pair.getName().asString()) { - case "value": - name = pair.getValue().asLiteralStringValueExpr().getValue(); - break; - case "useSegment": - if (!pair.getValue().asBooleanLiteralExpr().getValue()) { - segment = ""; - } - } - } - } - return segment + name; - } - - @Nonnull - private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ - if (typeDeclaration.getJavadoc().isPresent()) { - final var javadoc = typeDeclaration.getJavadoc().get(); - return javadoc.getDescription().toText() - + "\n\n" - + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) - .collect(Collectors.joining("\n")); - } - return ""; - } - - private static String type (MethodDeclaration method){ - if (method.getAnnotationByName("JsonNotification").isPresent()) - return "notification"; - if (method.getAnnotationByName("JsonRequest").isPresent()) - return "request"; - return ""; - } - - private static boolean isExported (MethodDeclaration method){ - return method.getAnnotationByName("JsonNotification").isPresent() - || method.getAnnotationByName("JsonRequest").isPresent(); - } - - private void printHeader () { - out.format("# KeY-API%n%n"); - } - - private void printFooter () { - } - - /* - private static boolean hasJsonSegment(TypeDeclaration it) { - return it.getAnnotationByName("JsonSegment").isPresent(); - } - - private static String getJsonSegment(TypeDeclaration it) { - var ae = it.getAnnotationByName("JsonSegment").get(); - return ae.asSingleMemberAnnotationExpr().getMemberValue() - .asLiteralStringValueExpr().getValue(); - } + * private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ + * var annotationExpr = m.getAnnotationByName("JsonNotification").or( + * () -> m.getAnnotationByName("JsonRequest")) + * .orElseThrow(); + * + * var segment = getJsonSegment(td) + "/"; + * String name = ""; + * + * if (annotationExpr.isMarkerAnnotationExpr()) { + * name = m.getNameAsString(); + * } else if (annotationExpr.isSingleMemberAnnotationExpr()) { + * var sma = annotationExpr.asSingleMemberAnnotationExpr(); + * name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); + * } else { + * var ne = annotationExpr.asNormalAnnotationExpr(); + * for (MemberValuePair pair : ne.getPairs()) { + * switch (pair.getName().asString()) { + * case "value": + * name = pair.getValue().asLiteralStringValueExpr().getValue(); + * break; + * case "useSegment": + * if (!pair.getValue().asBooleanLiteralExpr().getValue()) { + * segment = ""; + * } + * } + * } + * } + * return segment + name; + * } + * + * @Nonnull + * private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ + * if (typeDeclaration.getJavadoc().isPresent()) { + * final var javadoc = typeDeclaration.getJavadoc().get(); + * return javadoc.getDescription().toText() + * + "\n\n" + * + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) + * .collect(Collectors.joining("\n")); + * } + * return ""; + * } + * + * private static String type (MethodDeclaration method){ + * if (method.getAnnotationByName("JsonNotification").isPresent()) + * return "notification"; + * if (method.getAnnotationByName("JsonRequest").isPresent()) + * return "request"; + * return ""; + * } + * + * private static boolean isExported (MethodDeclaration method){ + * return method.getAnnotationByName("JsonNotification").isPresent() + * || method.getAnnotationByName("JsonRequest").isPresent(); + * } + * + * private void printHeader () { + * out.format("# KeY-API%n%n"); + * } + * + * private void printFooter () { + * } + * + * + * /* + * private static boolean hasJsonSegment(TypeDeclaration it) { + * return it.getAnnotationByName("JsonSegment").isPresent(); + * } + * + * private static String getJsonSegment(TypeDeclaration it) { + * var ae = it.getAnnotationByName("JsonSegment").get(); + * return ae.asSingleMemberAnnotationExpr().getMemberValue() + * .asLiteralStringValueExpr().getValue(); + * } */ } - diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java index 1c6c904553e..d053b9268d3 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -1,10 +1,26 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; + +import de.uka.ilkd.key.proof.Proof; + import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; import com.google.gson.*; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; @@ -13,18 +29,6 @@ import org.keyproject.key.api.remoteclient.ClientApi; import sun.misc.Unsafe; -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.reflect.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Supplier; - /** * @author Alexander Weigl * @version 1 (14.10.23) @@ -51,7 +55,8 @@ public static void main(String[] args) { runGenerator("server.py", PythionGenerator.PyApiGen::new); } - private static void runGenerator(String target, Function> api) { + private static void runGenerator(String target, + Function> api) { try { var n = api.apply(keyApi); Files.writeString(Paths.get(target), n.get()); @@ -65,7 +70,8 @@ private static Gson getGson() { .setPrettyPrinting() .registerTypeAdapter(Type.class, new JsonSerializer() { @Override - public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, + JsonSerializationContext context) { JsonObject json = (JsonObject) context.serialize(src); json.addProperty("kind", src.kind()); return json; @@ -76,7 +82,8 @@ public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, JsonSerializati private static void addServerEndpoint(Method method) { var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); - if (jsonSegment == null) return; + if (jsonSegment == null) + return; var segment = jsonSegment.value(); var req = method.getAnnotation(JsonRequest.class); @@ -131,27 +138,41 @@ private static Metamodel.Type getOrFindType(Class type) { return getOrFindType(type.getTypeParameters()[0].getClass()); } - if (type == Unsafe.class || type == Class.class || type == Constructor.class || type == Proof.class) { + if (type == Unsafe.class || type == Class.class || type == Constructor.class + || type == Proof.class) { throw new IllegalStateException("Forbidden class reached!"); } - if (type == String.class) return Metamodel.BuiltinType.STRING; - if (type == Integer.class) return Metamodel.BuiltinType.INT; - if (type == Double.class) return Metamodel.BuiltinType.DOUBLE; - if (type == Long.class) return Metamodel.BuiltinType.LONG; - if (type == Character.class) return Metamodel.BuiltinType.LONG; - if (type == File.class) return Metamodel.BuiltinType.STRING; - if (type == Boolean.class) return Metamodel.BuiltinType.BOOL; - if (type == Boolean.TYPE) return Metamodel.BuiltinType.BOOL; - - if (type == Integer.TYPE) return Metamodel.BuiltinType.INT; - if (type == Double.TYPE) return Metamodel.BuiltinType.DOUBLE; - if (type == Long.TYPE) return Metamodel.BuiltinType.LONG; - if (type == Character.TYPE) return Metamodel.BuiltinType.LONG; + if (type == String.class) + return Metamodel.BuiltinType.STRING; + if (type == Integer.class) + return Metamodel.BuiltinType.INT; + if (type == Double.class) + return Metamodel.BuiltinType.DOUBLE; + if (type == Long.class) + return Metamodel.BuiltinType.LONG; + if (type == Character.class) + return Metamodel.BuiltinType.LONG; + if (type == File.class) + return Metamodel.BuiltinType.STRING; + if (type == Boolean.class) + return Metamodel.BuiltinType.BOOL; + if (type == Boolean.TYPE) + return Metamodel.BuiltinType.BOOL; + + if (type == Integer.TYPE) + return Metamodel.BuiltinType.INT; + if (type == Double.TYPE) + return Metamodel.BuiltinType.DOUBLE; + if (type == Long.TYPE) + return Metamodel.BuiltinType.LONG; + if (type == Character.TYPE) + return Metamodel.BuiltinType.LONG; System.out.println(type); var t = types.stream().filter(it -> it.name().equals(type.getSimpleName())).findFirst(); - if (t.isPresent()) return t.get(); + if (t.isPresent()) + return t.get(); var a = createType(type); types.add(a); return a; @@ -161,8 +182,8 @@ private static Metamodel.Type createType(Class type) { final var documentation = findDocumentation(type); if (type.isEnum()) return new Metamodel.EnumType(type.getSimpleName(), - Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), - documentation); + Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), + documentation); var obj = new Metamodel.ObjectType(type.getSimpleName(), new ArrayList<>(), documentation); @@ -186,7 +207,8 @@ private static String findDocumentation(Class type) { e.printStackTrace(); return ""; } - } else return ""; + } else + return ""; } private static Path findFileForType(Class type) { @@ -226,7 +248,8 @@ private static void addClientEndpoint(Method method) { } } - private static String callMethodName(String method, String segment, String userValue, boolean useSegment) { + private static String callMethodName(String method, String segment, String userValue, + boolean useSegment) { if (!useSegment) { if (userValue == null || userValue.isBlank()) { return method; @@ -243,9 +266,11 @@ private static String callMethodName(String method, String segment, String userV } private static Metamodel.Type getOrFindType(Type genericReturnType) { - if (genericReturnType instanceof Class c) return getOrFindType(c); + if (genericReturnType instanceof Class c) + return getOrFindType(c); if (genericReturnType instanceof ParameterizedType pt) { - if (Objects.equals(pt.getRawType().getTypeName(), CompletableFuture.class.getTypeName())) { + if (Objects.equals(pt.getRawType().getTypeName(), + CompletableFuture.class.getTypeName())) { return getOrFindType(pt.getActualTypeArguments()[0]); } if (Objects.equals(pt.getRawType().getTypeName(), List.class.getTypeName())) { diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/Metamodel.java index 1a868f49a06..62146f0f5ee 100644 --- a/keyext.api.doc/src/main/java/Metamodel.java +++ b/keyext.api.doc/src/main/java/Metamodel.java @@ -1,7 +1,10 @@ -import org.jspecify.annotations.NullMarked; - +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ import java.util.List; +import org.jspecify.annotations.NullMarked; + /** * @author Alexander Weigl * @version 1 (29.10.23) @@ -10,11 +13,12 @@ public class Metamodel { public record KeyApi( List endpoints, - List types - ) { + List types) { } - sealed interface Endpoint { + sealed + + interface Endpoint { String name(); String documentation(); @@ -42,55 +46,67 @@ record ClientNotification(String name, String documentation, List args } record Field(String name, /*Type*/ String type, String documentation) { - Field(String name, String type) { + + Field(String name, String type) { this(name, type, ""); } - } +} - public sealed interface Type { - default String kind() { +public sealed + + +interface Type { + default String kind() { return getClass().getSimpleName(); } - String documentation(); + String documentation(); - String name(); - } + String name(); +} - enum BuiltinType implements Type { - INT, LONG, STRING, BOOL, DOUBLE; - @Override - public String documentation() { - return "built-in data type"; - } +enum BuiltinType implements Type { + INT, LONG, STRING, BOOL, DOUBLE; + + @Override + public String documentation() { + return "built-in data type"; + } + } record ListType(Type type, String documentation) implements Type { - @Override - public String name() { - return type().name() + "[]"; - } + + @Override + public String name() { + return type().name() + "[]"; + } + } record ObjectType(String typeName, List fields, String documentation) implements Type { - @Override - public String name() { - return typeName; - } + + @Override + public String name() { + return typeName; + } + } public record EitherType(Type a, Type b, String documentation) implements Type { - @Override - public String name() { - return "either"; - } + + @Override + public String name() { + return "either"; + } + } public record EnumType(String typeName, List values, String documentation) implements Type { - @Override - public String name() { - return typeName; - } + + @Override + public String name() { + return typeName; } -} +}} diff --git a/keyext.api.doc/src/main/java/PythionGenerator.java b/keyext.api.doc/src/main/java/PythionGenerator.java index a4d2018c328..9fc222a1221 100644 --- a/keyext.api.doc/src/main/java/PythionGenerator.java +++ b/keyext.api.doc/src/main/java/PythionGenerator.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Comparator; @@ -54,11 +57,11 @@ protected String asPython(Metamodel.Type t) { if (t instanceof Metamodel.BuiltinType bt) { return switch (bt) { - case INT -> "int"; - case LONG -> "int"; - case STRING -> "str"; - case BOOL -> "bool"; - case DOUBLE -> "float"; + case INT -> "int"; + case LONG -> "int"; + case STRING -> "str"; + case BOOL -> "bool"; + case DOUBLE -> "float"; }; } return t.name(); @@ -85,19 +88,21 @@ protected void run() { import enum import abc import typing - from abc import abstractmethod + from abc import abstractmethod """); server( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ServerRequest + || it instanceof Metamodel.ServerNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); client( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ClientRequest + || it instanceof Metamodel.ClientNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); } @@ -113,7 +118,7 @@ private void clientEndpoint(Metamodel.Endpoint endpoint) { out.format(" @abstractmethod%n"); if (endpoint instanceof Metamodel.ClientRequest sr) { out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, - asPython(sr.returnType())); + asPython(sr.returnType())); } else { out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); } @@ -128,7 +133,7 @@ private void server(Stream sorted) { class KeyServer(ServerBase):%n def __init__(self, endpoint : LspEndpoint): super().__init__(endpoint) - + """); sorted.forEach(this::serverEndpoint); } @@ -147,13 +152,15 @@ private void serverEndpoint(Metamodel.Endpoint endpoint) { if (endpoint instanceof Metamodel.ServerRequest sr) { out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, - asPython(sr.returnType())); + asPython(sr.returnType())); out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); - out.format(" return self._call_sync(\"%s\", %s)".formatted(endpoint.name(), params)); + out.format( + " return self._call_sync(\"%s\", %s)".formatted(endpoint.name(), params)); } else { out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" return self._call_async(\"%s\", %s)".formatted(endpoint.name(), params)); + out.format(" return self._call_async(\"%s\", %s)".formatted(endpoint.name(), + params)); } out.println(); out.println(); @@ -183,12 +190,13 @@ protected void run() { import abc import typing from abc import abstractmethod, ABCMeta - + """); metamodel.types().forEach(this::printType); - var names = metamodel.types().stream().map(it -> "\"%s\": %s".formatted(it.name(), it.name())) - .collect(Collectors.joining(",")); + var names = + metamodel.types().stream().map(it -> "\"%s\": %s".formatted(it.name(), it.name())) + .collect(Collectors.joining(",")); out.format("KEY_DATA_CLASSES = { %s }%n%n", names); } @@ -200,10 +208,9 @@ private void printType(Metamodel.Type type) { .formatted(it.name(), asPython(it.type()), it.documentation()))); out.format("\n def __init__(self%s):%n".formatted( - ot.fields().stream() - .map(Metamodel.Field::name) - .collect(Collectors.joining(", ", ", ", "")) - )); + ot.fields().stream() + .map(Metamodel.Field::name) + .collect(Collectors.joining(", ", ", ", "")))); if (ot.fields().isEmpty()) out.format(" pass%n%n"); @@ -220,4 +227,4 @@ private void printType(Metamodel.Type type) { out.println(); } } -} \ No newline at end of file +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java index b8f61b62272..9082242ee37 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java @@ -1,13 +1,18 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; -import com.google.gson.*; - import java.lang.reflect.Type; +import com.google.gson.*; + /** - * Stackoverflow post + * Stackoverflow + * post */ -public class GenericSerializer implements JsonSerializer /*, JsonDeserializer*/ { +public class GenericSerializer implements JsonSerializer /* , JsonDeserializer */ { private static final String CLASS_PROPERTY_NAME = "$type"; private final Gson gson; @@ -21,31 +26,31 @@ public GenericSerializer(Gson gson) { } /* - @Override - public Object deserialize(JsonElement json, Type typeOfT, - JsonDeserializationContext context) throws JsonParseException { - - Class actualClass; - if (json.isJsonObject()) { - JsonObject jsonObject = json.getAsJsonObject(); - String className = jsonObject.get(CLASS_PROPERTY_NAME).getAsString(); - try { - actualClass = Class.forName(className); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - throw new JsonParseException(e.getMessage()); - } - } else { - actualClass = typeOfT.getClass(); - } - - return gson.fromJson(json, actualClass); - } + * @Override + * public Object deserialize(JsonElement json, Type typeOfT, + * JsonDeserializationContext context) throws JsonParseException { + * + * Class actualClass; + * if (json.isJsonObject()) { + * JsonObject jsonObject = json.getAsJsonObject(); + * String className = jsonObject.get(CLASS_PROPERTY_NAME).getAsString(); + * try { + * actualClass = Class.forName(className); + * } catch (ClassNotFoundException e) { + * e.printStackTrace(); + * throw new JsonParseException(e.getMessage()); + * } + * } else { + * actualClass = typeOfT.getClass(); + * } + * + * return gson.fromJson(json, actualClass); + * } */ @Override public JsonElement serialize(Object src, Type typeOfSrc, - JsonSerializationContext context) { + JsonSerializationContext context) { JsonElement retValue = gson.toJsonTree(src); if (retValue.isJsonObject()) { retValue.getAsJsonObject().addProperty(CLASS_PROPERTY_NAME, src.getClass().getName()); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index f2a28731d3a..1e3a0539711 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -1,5 +1,18 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + import de.uka.ilkd.key.control.AbstractUserInterfaceControl; import de.uka.ilkd.key.control.DefaultUserInterfaceControl; import de.uka.ilkd.key.control.KeYEnvironment; @@ -23,11 +36,13 @@ import de.uka.ilkd.key.prover.TaskStartedInfo; import de.uka.ilkd.key.speclang.PositionedString; import de.uka.ilkd.key.util.KeYConstants; + +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSet; + import org.eclipse.lsp4j.jsonrpc.CompletableFutures; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.key_project.util.collection.ImmutableList; -import org.key_project.util.collection.ImmutableSet; import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.internal.NodeText; @@ -36,16 +51,6 @@ import org.keyproject.key.api.remoteapi.PrintOptions; import org.keyproject.key.api.remoteclient.ClientApi; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - public final class KeyApiImpl implements KeyApi { private final KeyIdentifications data = new KeyIdentifications(); @@ -74,8 +79,8 @@ public KeyApiImpl() { @Override @JsonRequest public CompletableFuture> examples() { - return CompletableFutures.computeAsync((c) -> - ExampleChooser.listExamples(ExampleChooser.lookForExamples()) + return CompletableFutures + .computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples()) .stream().map(ExampleDesc::from).toList()); } @@ -101,19 +106,20 @@ public CompletableFuture getVersion() { @Override public CompletableFuture> getAvailableMacros() { return CompletableFuture.completedFuture( - ProofMacroFacade.instance().getMacros().stream() - .map(ProofMacroDesc::from).toList() - ); + ProofMacroFacade.instance().getMacros().stream() + .map(ProofMacroDesc::from).toList()); } @Override public CompletableFuture> getAvailableScriptCommands() { return CompletableFuture.completedFuture( - ProofScriptCommandFacade.instance().getScriptCommands().stream().map(ProofScriptCommandDesc::from).toList()); + ProofScriptCommandFacade.instance().getScriptCommands().stream() + .map(ProofScriptCommandDesc::from).toList()); } @Override - public CompletableFuture script(ProofId proofId, String scriptLine, StreategyOptions options) { + public CompletableFuture script(ProofId proofId, String scriptLine, + StreategyOptions options) { return CompletableFuture.supplyAsync(() -> { var proof = data.find(proofId); var env = data.find(proofId.env()); @@ -129,14 +135,16 @@ public CompletableFuture script(ProofId proofId, String scriptLi } @Override - public CompletableFuture macro(ProofId proofId, String macroId, StreategyOptions options) { + public CompletableFuture macro(ProofId proofId, String macroId, + StreategyOptions options) { return CompletableFuture.supplyAsync(() -> { var proof = data.find(proofId); var env = data.find(proofId.env()); var macro = Objects.requireNonNull(ProofMacroFacade.instance().getMacro(macroId)); try { - var info = macro.applyTo(env.getUi(), proof, proof.openGoals(), null, clientListener); + var info = + macro.applyTo(env.getUi(), proof, proof.openGoals(), null, clientListener); return MacroStatistic.from(proofId, info); } catch (Exception e) { throw new RuntimeException(e); @@ -152,8 +160,8 @@ public CompletableFuture auto(ProofId proofId, StreategyOptions var env = data.find(proofId.env()); try { env.getProofControl().startAndWaitForAutoMode(proof); - //clientListener); - return null;//MacroStatistic.from(proofId, info); + // clientListener); + return null;// MacroStatistic.from(proofId, info); } catch (Exception e) { throw new RuntimeException(e); } @@ -172,7 +180,8 @@ public CompletableFuture dispose(ProofId id) { } @Override - public CompletableFuture> goals(ProofId proofId, boolean onlyOpened, boolean onlyEnabled) { + public CompletableFuture> goals(ProofId proofId, boolean onlyOpened, + boolean onlyEnabled) { return CompletableFuture.supplyAsync(() -> { var proof = data.find(proofId); if (onlyOpened && !onlyEnabled) { @@ -195,7 +204,7 @@ private List asNodeDesc(ProofId proofId, Stream nodes) { private NodeDesc asNodeDesc(ProofId proofId, Node it) { return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), - it.getNodeInfo().getScriptRuleApplication()); + it.getNodeInfo().getScriptRuleApplication()); } @Override @@ -207,12 +216,12 @@ public CompletableFuture tree(ProofId proofId) { } private NodeDesc asNodeDescRecursive(ProofId proofId, Node root) { - final List list = root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList(); + final List list = + root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList(); return new NodeDesc(new NodeId(proofId, root.serialNr()), - root.getNodeInfo().getBranchLabel(), - root.getNodeInfo().getScriptRuleApplication(), - list - ); + root.getNodeInfo().getBranchLabel(), + root.getNodeInfo().getScriptRuleApplication(), + list); } @Override @@ -282,7 +291,8 @@ public CompletableFuture> contracts(EnvironmentId envId) { return CompletableFuture.supplyAsync(() -> { var env = data.find(envId); var contracts = env.getAvailableContracts(); - return contracts.stream().map(it -> ContractDesc.from(envId, env.getServices(), it)).toList(); + return contracts.stream().map(it -> ContractDesc.from(envId, env.getServices(), it)) + .toList(); }); } @@ -291,7 +301,8 @@ public CompletableFuture openContract(ContractId contractId) { return CompletableFuture.supplyAsync(() -> { var env = data.find(contractId.envId()); var contracts = env.getAvailableContracts(); - var contract = contracts.stream().filter(it -> it.id() == contractId.contractId()).findFirst(); + var contract = + contracts.stream().filter(it -> it.id() == contractId.contractId()).findFirst(); if (contract.isPresent()) { try { var proof = env.createProof(contract.get().createProofObl(env.getInitConfig())); @@ -311,7 +322,8 @@ public CompletableFuture print(NodeId nodeId, PrintOptions options var node = data.find(nodeId); var env = data.find(nodeId.proofId().env()); var notInfo = new NotationInfo(); - final var layouter = new PosTableLayouter(options.width(), options.indentation(), options.pure()); + final var layouter = + new PosTableLayouter(options.width(), options.indentation(), options.pure()); var lp = new LogicPrinter(notInfo, env.getServices(), layouter); lp.printSequent(node.sequent()); @@ -332,8 +344,9 @@ public CompletableFuture> actions(NodeTextId printId, int p var goal = proof.getOpenGoal(node); var nodeText = data.find(printId); var pis = nodeText.table().getPosInSequent(pos, filter); - return new TermActionUtil(printId, data.find(printId.nodeId().proofId().env()), pis, goal) - .getActions(); + return new TermActionUtil(printId, data.find(printId.nodeId().proofId().env()), pis, + goal) + .getActions(); }); } @@ -365,19 +378,21 @@ public CompletableFuture loadExample(String id) { KeYEnvironment env = null; try { var loader = control.load(JavaProfile.getDefaultProfile(), - ex.getObligationFile(), null, null, null, null, true, null); + ex.getObligationFile(), null, null, null, null, true, null); InitConfig initConfig = loader.getInitConfig(); env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); var envId = new EnvironmentId(env.toString()); data.register(envId, env); proof = Objects.requireNonNull(env.getLoadedProof()); var proofId = new ProofId(envId, proof.name().toString()); return data.register(proofId, proof); } catch (ProblemLoaderException e) { - if (proof != null) proof.dispose(); - if (env != null) env.dispose(); + if (proof != null) + proof.dispose(); + if (env != null) + env.dispose(); throw new RuntimeException(e); } } @@ -390,17 +405,19 @@ public CompletableFuture loadProblem(ProblemDefinition problem) { return CompletableFutures.computeAsync((c) -> { Proof proof = null; KeYEnvironment env = null; - /* var loader = control.load(JavaProfile.getDefaultProfile(), - ex.getObligationFile(), null, null, null, null, true, null); - InitConfig initConfig = loader.getInitConfig(); - - env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); - var envId = new EnvironmentId(env.toString()); - data.register(envId, env); - proof = Objects.requireNonNull(env.getLoadedProof()); - var proofId = new ProofId(envId, proof.name().toString()); - return data.register(proofId, proof);*/ + /* + * var loader = control.load(JavaProfile.getDefaultProfile(), + * ex.getObligationFile(), null, null, null, null, true, null); + * InitConfig initConfig = loader.getInitConfig(); + * + * env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + * loader.getProofScript(), loader.getResult()); + * var envId = new EnvironmentId(env.toString()); + * data.register(envId, env); + * proof = Objects.requireNonNull(env.getLoadedProof()); + * var proofId = new ProofId(envId, proof.name().toString()); + * return data.register(proofId, proof); + */ return null; }); @@ -415,18 +432,20 @@ public CompletableFuture loadKey(String content) { final var tempFile = File.createTempFile("json-rpc-", ".key"); Files.writeString(tempFile.toPath(), content); var loader = control.load(JavaProfile.getDefaultProfile(), - tempFile, null, null, null, null, true, null); + tempFile, null, null, null, null, true, null); InitConfig initConfig = loader.getInitConfig(); env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); var envId = new EnvironmentId(env.toString()); data.register(envId, env); proof = Objects.requireNonNull(env.getLoadedProof()); var proofId = new ProofId(envId, proof.name().toString()); return data.register(proofId, proof); } catch (ProblemLoaderException | IOException e) { - if (proof != null) proof.dispose(); - if (env != null) env.dispose(); + if (proof != null) + proof.dispose(); + if (env != null) + env.dispose(); throw new RuntimeException(e); } }); @@ -444,16 +463,16 @@ public CompletableFuture> load(LoadParams params) KeYEnvironment env = null; try { var loader = control.load(JavaProfile.getDefaultProfile(), - params.keyFile(), - params.classPath(), - params.bootClassPath(), - params.includes(), - null, - true, - null); + params.keyFile(), + params.classPath(), + params.bootClassPath(), + params.includes(), + null, + true, + null); InitConfig initConfig = loader.getInitConfig(); env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); var envId = new EnvironmentId(env.toString()); data.register(envId, env); if ((proof = env.getLoadedProof()) != null) { @@ -463,8 +482,10 @@ public CompletableFuture> load(LoadParams params) return Either.forLeft(envId); } } catch (ProblemLoaderException e) { - if (proof != null) proof.dispose(); - if (env != null) env.dispose(); + if (proof != null) + proof.dispose(); + if (env != null) + env.dispose(); throw new RuntimeException(e); } }); @@ -502,7 +523,9 @@ public void loadingStarted(AbstractProblemLoader loader) { } @Override - public void loadingFinished(AbstractProblemLoader loader, IPersistablePO.LoadedPOContainer poContainer, ProofAggregate proofList, AbstractProblemLoader.ReplayResult result) throws ProblemLoaderException { + public void loadingFinished(AbstractProblemLoader loader, + IPersistablePO.LoadedPOContainer poContainer, ProofAggregate proofList, + AbstractProblemLoader.ReplayResult result) throws ProblemLoaderException { super.loadingFinished(loader, poContainer, proofList, result); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java index f28001e8c15..2f948413e72 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java @@ -1,4 +1,4 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; - -import org.keyproject.key.api.data.KeyIdentifications.NodeId; - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index b0491145cda..53293b35680 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -1,6 +1,16 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.io.*; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.concurrent.ExecutionException; +import javax.annotation.Nullable; + import com.google.gson.GsonBuilder; import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.websocket.jakarta.WebSocketLauncherBuilder; @@ -11,13 +21,6 @@ import picocli.CommandLine; import picocli.CommandLine.Option; -import javax.annotation.Nullable; -import java.io.*; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.concurrent.ExecutionException; - /** * @author Alexander Weigl * @version 1 (07.10.23) @@ -26,7 +29,7 @@ public class StartServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); - //region CLI arguments + // region CLI arguments @Option(names = "--std", description = "use stdout and stdin for communication") boolean stdStreams; @Option(names = "--trace", description = "use stdout and stdin for communication") @@ -41,19 +44,21 @@ public class StartServer implements Runnable { Integer clientPort; - @Option(names = "--infile", paramLabel = "FILE or PIPE", description = "read from named pipe or file") + @Option(names = "--infile", paramLabel = "FILE or PIPE", + description = "read from named pipe or file") @Nullable File inFile; - @Option(names = "--outfile", paramLabel = "FILE or PIPE", description = "write to named pipe or file") + @Option(names = "--outfile", paramLabel = "FILE or PIPE", + description = "write to named pipe or file") File outFile; - @Option(names = {"-h", "--help"}, usageHelp = true, description = "display a help message") + @Option(names = { "-h", "--help" }, usageHelp = true, description = "display a help message") boolean helpRequested = false; @Option(names = "--websocket") boolean websocket = false; - //endregion + // endregion public static void main(String[] args) { new CommandLine(new StartServer()).execute(args); @@ -159,12 +164,11 @@ public static Launcher launch(OutputStream out, InputStream in, KeyAp .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - //if (localServices != null && !localServices.isEmpty()) + // if (localServices != null && !localServices.isEmpty()) launcherBuilder.setLocalService(keyApi); - //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) + // if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) launcherBuilder.setRemoteInterface(ClientApi.class); return launcherBuilder.create(); } } - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java index 31714a361d7..c65a93d677a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -1,5 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.control.ProofControl; import de.uka.ilkd.key.logic.Name; @@ -9,56 +16,53 @@ import de.uka.ilkd.key.pp.PosInSequent; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.*; -import org.jspecify.annotations.NonNull; + import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; + +import org.jspecify.annotations.NonNull; import org.keyproject.key.api.data.KeyIdentifications; import org.keyproject.key.api.data.KeyIdentifications.NodeTextId; import org.keyproject.key.api.data.TermActionDesc; import org.keyproject.key.api.data.TermActionKind; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - /** * @author Alexander Weigl * @version 1 (29.10.23) */ public class TermActionUtil { private static final Set CLUTTER_RULESETS = - Set.of(new Name("notHumanReadable"), - new Name("obsolete"), - new Name("pullOutQuantifierAll"), - new Name("pullOutQuantifierEx")); + Set.of(new Name("notHumanReadable"), + new Name("obsolete"), + new Name("pullOutQuantifierAll"), + new Name("pullOutQuantifierEx")); private static final Set CLUTTER_RULES = Set.of( - new Name("cut_direct_r"), - new Name("cut_direct_l"), - new Name("case_distinction_r"), - new Name("case_distinction_l"), - new Name("local_cut"), - new Name("commute_and_2"), - new Name("commute_or_2"), - new Name("boxToDiamond"), - new Name("pullOut"), - new Name("typeStatic"), - new Name("less_is_total"), - new Name("less_zero_is_total"), - new Name("applyEqReverse"), + new Name("cut_direct_r"), + new Name("cut_direct_l"), + new Name("case_distinction_r"), + new Name("case_distinction_l"), + new Name("local_cut"), + new Name("commute_and_2"), + new Name("commute_or_2"), + new Name("boxToDiamond"), + new Name("pullOut"), + new Name("typeStatic"), + new Name("less_is_total"), + new Name("less_zero_is_total"), + new Name("applyEqReverse"), - // the following are used for drag'n'drop interactions - new Name("eqTermCut"), - new Name("instAll"), - new Name("instEx") - ); + // the following are used for drag'n'drop interactions + new Name("eqTermCut"), + new Name("instAll"), + new Name("instEx")); private static final Set FILTER_SCRIPT_COMMANDS = Set.of( - "exit", - "leave", - "javascript", - "skip", - "macro", - "rule", - "script"); + "exit", + "leave", + "javascript", + "skip", + "macro", + "rule", + "script"); private final PosInSequent pos; private final Goal goal; @@ -67,7 +71,8 @@ public class TermActionUtil { private final List actions = new ArrayList<>(1024); private final NodeTextId nodeTextId; - public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment env, @NonNull PosInSequent pos, @NonNull Goal goal) { + public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment env, + @NonNull PosInSequent pos, @NonNull Goal goal) { this.pos = pos; this.goal = goal; this.nodeTextId = nodeTextId; @@ -75,8 +80,10 @@ public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment ProofControl c = env.getUi().getProofControl(); final ImmutableList builtInRules = c.getBuiltInRule(goal, occ); for (ProofMacro macro : ProofMacroFacade.instance().getMacros()) { - var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "macro:" + macro.getScriptCommandName()); - TermActionDesc ta = new TermActionDesc(id, macro.getName(), macro.getDescription(), macro.getCategory(), TermActionKind.Macro); + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), + "macro:" + macro.getScriptCommandName()); + TermActionDesc ta = new TermActionDesc(id, macro.getName(), macro.getDescription(), + macro.getCategory(), TermActionKind.Macro); add(ta); } ImmutableList findTaclet = c.getFindTaclet(goal, occ); @@ -86,16 +93,18 @@ public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment for (TacletApp tacletApp : find) { - var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "find:" + tacletApp.rule()); + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), + "find:" + tacletApp.rule()); TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), - tacletApp.rule().toString(), "", TermActionKind.Taclet); + tacletApp.rule().toString(), "", TermActionKind.Taclet); add(ta); } for (TacletApp tacletApp : nofind) { - var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "nofind:" + tacletApp.rule()); + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), + "nofind:" + tacletApp.rule()); TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), - tacletApp.rule().toString(), "", TermActionKind.Taclet); + tacletApp.rule().toString(), "", TermActionKind.Taclet); add(ta); } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 67871cec674..53cd4cec09c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -1,49 +1,54 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.adapters; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; + +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.macros.ProofMacro; + import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.macros.ProofMacro; import org.keyproject.key.api.data.MacroDescription; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Type; - /** * @author Alexander Weigl * @version 1 (14.10.23) */ public class KeyAdapter { - //private final BiMap> map = HashBiMap.create(1024); - //private final TypeAdapter adaptor; + // private final BiMap> map = HashBiMap.create(1024); + // private final TypeAdapter adaptor; public KeyAdapter(GsonBuilder gson) { gson.registerTypeAdapter(File.class, new FileTypeAdapter()); - //gson.registerTypeAdapter(Function.class, new FunctionSerializer()); - //gson.registerTypeAdapter(ProofMacro.class, new MacroSerializer()); + // gson.registerTypeAdapter(Function.class, new FunctionSerializer()); + // gson.registerTypeAdapter(ProofMacro.class, new MacroSerializer()); } /* - //translating entities to identification strings - public void insert(Identifiable p) { - var id = p.identification(); - if (!map.containsKey(id)) { - map.put(id, new WeakReference<>(p)); - } - } - - public Object find(String id) { - return map.get(id).get(); - } - //endregion - */ + * //translating entities to identification strings + * public void insert(Identifiable p) { + * var id = p.identification(); + * if (!map.containsKey(id)) { + * map.put(id, new WeakReference<>(p)); + * } + * } + * + * public Object find(String id) { + * return map.get(id).get(); + * } + * //endregion + */ static class MacroSerializer implements JsonSerializer { @Override - public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(ProofMacro src, Type typeOfSrc, + JsonSerializationContext context) { return context.serialize(MacroDescription.from(src)); } } @@ -62,7 +67,8 @@ public File read(JsonReader in) throws IOException { static class FunctionSerializer implements JsonSerializer { @Override - public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(Function src, Type typeOfSrc, + JsonSerializationContext context) { var obj = new JsonObject(); obj.add("name", context.serialize(src.name().toString())); obj.add("skolemConstant", context.serialize(src.isSkolemConstant())); @@ -76,7 +82,8 @@ public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationCont public static class ThrowableAdapter implements JsonSerializer { @Override - public JsonElement serialize(Throwable src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(Throwable src, Type typeOfSrc, + JsonSerializationContext context) { var obj = new JsonObject(); obj.add("$class", context.serialize(src.getClass().getSimpleName())); obj.add("message", context.serialize(src.getMessage())); @@ -85,16 +92,22 @@ public JsonElement serialize(Throwable src, Type typeOfSrc, JsonSerializationCon } } - /*class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { - @Override - public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - return (Identifiable) find(json.getAsString()); - } - - @Override - public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerializationContext context) { - insert(src); - return context.serialize(src.identification()); - } - }*/ + /* + * class IdentifiableTypeAdapter implements JsonSerializer, + * JsonDeserializer { + * + * @Override + * public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext + * context) throws JsonParseException { + * return (Identifiable) find(json.getAsString()); + * } + * + * @Override + * public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerializationContext + * context) { + * insert(src); + * return context.serialize(src.identification()); + * } + * } + */ } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java index bbc28eec1ec..522f32d9b3b 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java @@ -4,4 +4,4 @@ * @author Alexander Weigl * @version 1 (14.10.23) */ -package org.keyproject.key.api.adapters; \ No newline at end of file +package org.keyproject.key.api.adapters; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java index 531bc2fb56d..b6a363a6f6e 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.java.Services; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java index 1868871c0e3..3b7238f676e 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -1,9 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import de.uka.ilkd.key.logic.op.Function; - import java.util.List; +import de.uka.ilkd.key.logic.op.Function; + /** * @author Alexander Weigl * @version 1 (15.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java index 6d66823142a..3f512c76fbd 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java @@ -1,16 +1,20 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; +import java.lang.ref.WeakReference; +import java.util.Objects; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import org.jspecify.annotations.NonNull; import org.keyproject.key.api.internal.NodeText; -import java.lang.ref.WeakReference; -import java.util.Objects; - /** * @author Alexander Weigl * @version 1 (29.10.23) @@ -19,27 +23,31 @@ public class KeyIdentifications { private final BiMap mapEnv = HashBiMap.create(16); public KeyEnvironmentContainer getContainer(EnvironmentId environmentId) { - return Objects.requireNonNull(mapEnv.get(environmentId), "Could not find environment for id" + environmentId); + return Objects.requireNonNull(mapEnv.get(environmentId), + "Could not find environment for id" + environmentId); } public ProofContainer getContainer(ProofId proofId) { return Objects.requireNonNull(getContainer(proofId.env()).mapProof.get(proofId), - "Could not find proof for id" + proofId); + "Could not find proof for id" + proofId); } public KeYEnvironment find(EnvironmentId envid) { - return Objects.requireNonNull(getContainer(envid).env.get(), "Environment was removed by gc"); + return Objects.requireNonNull(getContainer(envid).env.get(), + "Environment was removed by gc"); } @NonNull public Proof find(ProofId proofId) { - return Objects.requireNonNull(getContainer(proofId).wProof.get(), "Could not find a proof for id " + proofId); + return Objects.requireNonNull(getContainer(proofId).wProof.get(), + "Could not find a proof for id " + proofId); } @NonNull public NodeText find(NodeTextId nodeTextId) { - return Objects.requireNonNull(getContainer(nodeTextId.nodeId().proofId()).mapGoalText.get(nodeTextId), - "Could not find a print-out with the id " + nodeTextId); + return Objects.requireNonNull( + getContainer(nodeTextId.nodeId().proofId()).mapGoalText.get(nodeTextId), + "Could not find a print-out with the id " + nodeTextId); } public void dispose(NodeTextId nodeTextId) { @@ -54,7 +62,8 @@ public void dispose(ProofId id) { } public Node find(NodeId nodeId) { - @NonNull Proof p = find(nodeId.proofId); + @NonNull + Proof p = find(nodeId.proofId); var opt = p.findAny(it -> it.serialNr() == nodeId.nodeId()); return Objects.requireNonNull(opt, "Could not find node with serialNr " + nodeId.nodeId); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java index 85ec900cd57..6d0a47c9a3f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import java.io.File; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java index 0274bc38b30..fc2a8ba0e95 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacro; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java index b0c2397d1f3..6825f99a90c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; @@ -6,10 +9,9 @@ * @author Alexander Weigl * @version 1 (13.10.23) */ -public record MacroStatistic(KeyIdentifications.ProofId proofId, String macroId, boolean cancelled, int appliedRules, +public record MacroStatistic(KeyIdentifications.ProofId proofId, String macroId, int appliedRules, int closedGoals) { public static MacroStatistic from(KeyIdentifications.ProofId proofId, ProofMacroFinishedInfo info) { - return new MacroStatistic(proofId, info.getMacro().getName(), info.isCancelled(), - info.getAppliedRules(), info.getClosedGoals()); + return new MacroStatistic(proofId, info.getMacro().getName(), info.getAppliedRules(), info.getClosedGoals()); } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java index eda5e693f64..cd306e53816 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -1,9 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import org.jspecify.annotations.Nullable; - import java.util.List; +import org.jspecify.annotations.Nullable; + /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java index 333b24f1c73..df4eb11f82f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java index 640c25371d6..dbb0e899496 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java index d952ea3a654..be69d976fc7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java @@ -1,10 +1,13 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import org.jspecify.annotations.Nullable; - import java.util.List; +import org.jspecify.annotations.Nullable; + /** * @author Alexander Weigl * @version 1 (15.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java index 31981c61beb..f1faea9cf12 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacro; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java index f6eef733d08..0f086d8f936 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java index 66df02ee6b0..797f8ccb16f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -1,9 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import de.uka.ilkd.key.logic.sort.Sort; - import java.util.List; +import de.uka.ilkd.key.logic.sort.Sort; + /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java index b73ee35b7b5..ea804f0562b 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java index b27ac08a279..d9c619f4dea 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import org.keyproject.key.api.data.KeyIdentifications.TermActionId; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java index cc7d9aec71a..0a371aa48e4 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java index 7f8c9564aa9..99a258f79d4 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; public enum TraceValue { diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java index 213bb6b9dbe..7f8509df70c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java index 5750fea944d..84898829e9a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java @@ -1,8 +1,9 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.internal; import de.uka.ilkd.key.pp.InitialPositionTable; -import de.uka.ilkd.key.pp.PositionTable; -import de.uka.ilkd.key.proof.Node; /** * @author Alexander Weigl diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java index e84a0152760..dc8fb6362c6 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java @@ -1,5 +1,11 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.ContractDesc; @@ -7,9 +13,6 @@ import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.SortDesc; -import java.util.List; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java index 6c52dfd39aa..5f19f881e9d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java @@ -1,12 +1,14 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.gui.Example; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - import java.util.List; import java.util.concurrent.CompletableFuture; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + @JsonSegment("examples") public interface ExampleApi { @JsonRequest("list") diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java index c0091943899..e2f00758a72 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.gui.Example; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java index 959ed91570c..68a9e263708 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -1,14 +1,17 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.data.NodeTextDesc; import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; - -import java.util.List; -import java.util.concurrent.CompletableFuture; +import org.keyproject.key.api.data.NodeTextDesc; /** * @author Alexander Weigl diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index 56a166f9af7..a94b35967af 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -1,7 +1,11 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; /** * The combined interface that is provided by KeY. */ -public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi, ProofLoadApi{ +public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, + GoalApi, EnvApi, ProofLoadApi { } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java index f101a47f16a..ea2c8174a58 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java @@ -1,14 +1,17 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.ProofMacroDesc; import org.keyproject.key.api.data.ProofScriptCommandDesc; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import org.keyproject.key.api.data.KeyIdentifications.*; - @JsonSegment("meta") public interface MetaApi { @JsonRequest("version") diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java index 6555b2a16fb..4144c9e6877 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java index e496b7a4d38..8d0fc27154d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java @@ -1,25 +1,31 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import de.uka.ilkd.key.proof.Statistics; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.MacroStatistic; import org.keyproject.key.api.data.NodeDesc; import org.keyproject.key.api.data.StreategyOptions; -import java.util.List; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) */ public interface ProofApi { @JsonRequest - CompletableFuture script(ProofId proof, String scriptLine, StreategyOptions options); + CompletableFuture script(ProofId proof, String scriptLine, + StreategyOptions options); @JsonRequest - CompletableFuture macro(ProofId proof, String macroId, StreategyOptions options); + CompletableFuture macro(ProofId proof, String macroId, + StreategyOptions options); @JsonRequest CompletableFuture auto(ProofId proof, StreategyOptions options); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java index 9ffedadf57d..2b5f5e78187 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java @@ -1,19 +1,20 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.Proof; +import java.util.concurrent.CompletableFuture; + import de.uka.ilkd.key.proof.io.ProblemLoaderException; + import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.data.KeyIdentifications; import org.keyproject.key.api.data.KeyIdentifications.EnvironmentId; import org.keyproject.key.api.data.KeyIdentifications.ProofId; import org.keyproject.key.api.data.LoadParams; import org.keyproject.key.api.data.ProblemDefinition; -import java.util.concurrent.CompletableFuture; - /** * Functionalities for loading proofs either from a built-in example, or from a set of files. * @@ -24,6 +25,7 @@ public interface ProofLoadApi { /** * I am not sure whether this is helpful. Mainly a feature for testing?! + * * @param id * @return */ @@ -53,5 +55,6 @@ public interface ProofLoadApi { * @throws ProblemLoaderException if something went wrong */ @JsonRequest - CompletableFuture> load(LoadParams params) throws ProblemLoaderException; -} \ No newline at end of file + CompletableFuture> load(LoadParams params) + throws ProblemLoaderException; +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java index d3225919d63..cd4aa88b146 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java @@ -1,14 +1,17 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.KeyIdentifications.ProofId; import org.keyproject.key.api.data.KeyIdentifications.TreeNodeId; import org.keyproject.key.api.data.TreeNodeDesc; -import java.util.List; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java index 00e85b9e021..bcbff9a04ff 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java @@ -1,12 +1,15 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.TraceValue; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) @@ -15,9 +18,15 @@ public interface ServerManagement { /** * Shutdown Request (:leftwards_arrow_with_hook:) - * The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. + * The shutdown request is sent from the client to the server. It asks the server to shut down, + * but to not exit (otherwise the response might not be delivered correctly to the client). + * There is a separate exit notification that asks the server to exit. Clients must not send any + * notifications other than exit or requests to a server to which they have sent a shutdown + * request. Clients should also wait with sending the exit notification until they have received + * a response from the shutdown request. *

    - * If a server receives requests after a shutdown request those requests should error with InvalidRequest. + * If a server receives requests after a shutdown request those requests should error with + * InvalidRequest. *

    * Request: *

    @@ -33,7 +42,8 @@ public interface ServerManagement { /** * Exit Notification (:arrow_right:) - * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. + * A notification to ask the server to exit its process. The server should exit with success + * code 0 if the shutdown request has been received before; otherwise with error code 1. *

    * Notification: *

    diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java index ca086eae72f..fe34e79927e 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -1,14 +1,18 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nullable; + import de.uka.ilkd.key.prover.TaskFinishedInfo; import de.uka.ilkd.key.prover.TaskStartedInfo; + import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import javax.annotation.Nullable; -import java.util.concurrent.CompletableFuture; - @JsonSegment("client") public interface ClientApi { @JsonNotification @@ -16,9 +20,13 @@ public interface ClientApi { /** * LogTrace Notification (:arrow_left:) - * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. + * A notification to log the trace of the server’s execution. The amount and content of these + * notifications depends on the current trace configuration. If trace is 'off', the server + * should not send any logTrace notification. If trace is 'messages', the server should not add + * the 'verbose' field in the LogTraceParams. *

    - * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. + * $/logTrace should be used for systematic trace reporting. For single debugging messages, the + * server should send window/logMessage notifications. *

    * Notification: *

    @@ -27,11 +35,12 @@ public interface ClientApi { */ @JsonNotification void logTrace(LogTraceParams params); - //region Window + // region Window /** * ShowMessage Notification (:arrow_left:) - * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. + * The show message notification is sent from a server to a client to ask the client to display + * a particular message in the user interface. *

    * Notification: *

    @@ -45,7 +54,9 @@ public interface ClientApi { /** * ShowMessage Request (:arrow_right_hook:) - * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. + * The show message request is sent from a server to a client to ask the client to display a + * particular message in the user interface. In addition to the show message notification the + * request allows to pass actions and to wait for an answer from the client. */ @JsonRequest @Nullable @@ -56,7 +67,8 @@ public interface ClientApi { * Show Document Request (:arrow_right_hook:) * New in version 3.16.0 *

    - * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. + * The show document request is sent from a server to a client to ask the client to display a + * particular resource referenced by a URI in the user interface. *

    * property path (optional): window.showDocument * property type: ShowDocumentClientCapabilities defined as follows: @@ -66,7 +78,9 @@ public interface ClientApi { void taskFinished(TaskFinishedInfo info); + void taskProgress(int position); + void taskStarted(TaskStartedInfo info); - //endregion + // endregion } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java index 7ae00a584e7..d1ae6245f0d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; record LogMessageParams( diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java index b5995ff5220..9328544be6c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; import org.eclipse.lsp4j.jsonrpc.validation.NonNull; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java index df586cac66d..79e94cc39bb 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public record MessageActionItem( diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java index cb8c20dd311..8564f136f36 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java @@ -1,28 +1,31 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public enum MessageType { - Unused, - /** - * An error message. - */ - Error, - /** - * A warning message. - */ - Warning, - /** - * An information message. - */ - Info, - /** - * A log message. - */ - Log, - /** - * A debug message. - * - * @proposed - * @since 3.18.0 - */ - Debug - } + Unused, + /** + * An error message. + */ + Error, + /** + * A warning message. + */ + Warning, + /** + * An information message. + */ + Info, + /** + * A log message. + */ + Log, + /** + * A debug message. + * + * @proposed + * @since 3.18.0 + */ + Debug +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java index 17502b1a910..1e3050bbfde 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; import de.uka.ilkd.key.pp.Range; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java index b91a100858a..bb455cbebd5 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public record ShowDocumentResult( diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java index 9bf22a6f552..5b0a6fc0286 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public record ShowMessageParams( @@ -10,5 +13,5 @@ public record ShowMessageParams( * The actual message. */ String message) { - + } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java index 49e662c6524..6dcc7164acc 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; import java.util.List; diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java index b275265b6c7..5f2335e5ef3 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -1,11 +1,15 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nullable; + import de.uka.ilkd.key.prover.TaskFinishedInfo; import de.uka.ilkd.key.prover.TaskStartedInfo; -import org.keyproject.key.api.remoteclient.*; -import javax.annotation.Nullable; -import java.util.concurrent.CompletableFuture; +import org.keyproject.key.api.remoteclient.*; class SimpleClient implements ClientApi { diff --git a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index 5e0c87e06f5..9e7869bdfaa 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -1,13 +1,8 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; -import org.eclipse.lsp4j.jsonrpc.Launcher; -import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.keyproject.key.api.remoteapi.KeyApi; -import org.keyproject.key.api.remoteclient.ClientApi; - import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; @@ -18,6 +13,14 @@ import java.util.logging.Level; import java.util.logging.Logger; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteclient.ClientApi; + public class TestRpc { private Future clientListening, serverListening; private KeyApi keyApi; diff --git a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java index 5d7647eaf34..5c02f2ba138 100644 --- a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java +++ b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java @@ -3,6 +3,8 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.exploration; +import java.io.File; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.nparser.KeyIO; @@ -10,13 +12,13 @@ import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; + +import org.key_project.util.collection.ImmutableList; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.key_project.util.collection.ImmutableList; - -import java.io.File; import static org.junit.jupiter.api.Assertions.*; @@ -83,7 +85,7 @@ public void testAdditionAntec() { assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -125,7 +127,7 @@ public void testAdditionSucc() { testAddition(withAddedTerm, justification, added, false); assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -146,9 +148,9 @@ public void testChangeFormula() { assertSame(1, goals.size(), "Prerequisite for test"); Sequent sequent = goals.head().node().sequent(); PosInOccurrence pio = - new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); + new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); expService.applyChangeFormula(goals.head(), pio, sequent.succedent().get(0).formula(), - change); + change); ImmutableList newCreatedGoals = currentProof.openGoals(); assertEquals(2, newCreatedGoals.size(), "Two new goals created"); @@ -166,7 +168,7 @@ public void testChangeFormula() { assertNotNull(justificationBranch.node().lookup(ExplorationNodeData.class)); assertEquals(new Name("hide_right"), hideNode.getAppliedRuleApp().rule().name(), - "Hide Right was applied"); + "Hide Right was applied"); // set all goals to interactive justificationBranch.setEnabled(true); // perform proof, it has to close @@ -184,34 +186,34 @@ public void testChangeFormula() { */ private void testAddition(Goal withAddedTerm, Goal justification, Term added, boolean antec) { Semisequent semiSeqAdded = - antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfAdded = - antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); Semisequent semiSeqUntouched = - !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfUntouched = - !antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + !antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); assertSame(semiSeqAdded.size(), parentSemiSeqOfAdded.size() + 1, - "The size of the added semisequent has changed"); + "The size of the added semisequent has changed"); assertEquals(semiSeqAdded.get(0).formula(), added, "Added Term is indeed added"); assertFalse(justification.isAutomatic(), "Justification branch is marked as interactive"); assertSame(semiSeqUntouched.size(), parentSemiSeqOfUntouched.size(), - "The size if untouched semisequents is the same"); + "The size if untouched semisequents is the same"); assertEquals(semiSeqUntouched, parentSemiSeqOfUntouched, - "The untouched semisequents are equal"); + "The untouched semisequents are equal"); Node parent = withAddedTerm.node().parent(); assertEquals(parent, justification.node().parent(), "Both nodes have the same parent"); assertEquals(new Name("cut"), parent.getAppliedRuleApp().rule().name(), - "The addition was inserted using the cut rule"); + "The addition was inserted using the cut rule"); } /** diff --git a/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java b/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java index 087e4c5d59f..045e315d72c 100644 --- a/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java +++ b/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java @@ -35,9 +35,12 @@ public void actionPerformed(ActionEvent e) { // This method delegates the request only to the UserInterfaceControl // which implements the functionality. No functionality is allowed in this method body! new Thread(() -> { - MainWindow.getInstance().getMediator().getUI().getProofControl() - .stopAndWaitAutoMode(); - ThreadUtilities.invokeOnEventQueue(() -> exitButton.setEnabled(true)); + try { + MainWindow.getInstance().getMediator().getUI().getProofControl() + .stopAndWaitAutoMode(); + ThreadUtilities.invokeOnEventQueue(() -> exitButton.setEnabled(true)); + } catch (InterruptedException ignore) { + } }).start(); } }; From 82f54f01e8d5424e837d2dab50748f949517314f Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Thu, 5 Oct 2023 00:59:22 +0200 Subject: [PATCH 10/50] some functions for tff --- .../java/de/uka/ilkd/key/gui/Example.java | 196 +++++++++++++++ .../de/uka/ilkd/key/gui/ExampleChooser.java | 179 -------------- keyext.api/build.gradle | 6 + .../org/keyproject/key/FileTypeAdapter.java | 20 ++ .../org/keyproject/key/remoteapi/KeyApi.java | 58 +++++ .../keyproject/key/remoteapi/KeyApiImpl.java | 56 +++++ .../key/remoteapi/KeyExampleApi.java | 14 ++ .../keyproject/key/remoteapi/KeyMetaApi.java | 21 ++ .../key/remoteapi/MacroDescription.java | 9 + .../org/keyproject/key/remoteapi/Main.java | 63 +++++ .../org/keyproject/key/remoteapi/ProofId.java | 4 + .../key/remoteapi/ProofLoading.java | 67 ++++++ .../keyproject/key/remoteapi/TraceValue.java | 5 + .../keyproject/key/remoteclient/Client.java | 53 +++++ .../key/remoteclient/ClientApi.java | 224 ++++++++++++++++++ .../key/remoteclient/SimpleClient.java | 9 + settings.gradle | 2 + 17 files changed, 807 insertions(+), 179 deletions(-) create mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java create mode 100644 keyext.api/build.gradle create mode 100644 keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java new file mode 100644 index 00000000000..85a85b65df1 --- /dev/null +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java @@ -0,0 +1,196 @@ +package de.uka.ilkd.key.gui; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; + +/** + * This class wraps a {@link java.io.File} and has a special {@link #toString()} method only using the + * short file name w/o path. + *

    + * Used for displaying files in the examples list w/o prefix + */ +public class Example { + private static final Logger LOGGER = LoggerFactory.getLogger(Example.class); + /** + * This constant is accessed by the eclipse based projects. + */ + public static final String KEY_FILE_NAME = "project.key"; + + private static final String PROOF_FILE_NAME = "project.proof"; + + /** + * The default category under which examples range if they do not have {@link #KEY_PATH} + * set. + */ + public static final String DEFAULT_CATEGORY_PATH = "Unsorted"; + + /** + * The {@link Properties} key to specify the path in the tree. + */ + public static final String KEY_PATH = "example.path"; + + /** + * The {@link Properties} key to specify the name of the example. Directory name if left + * open. + */ + public static final String KEY_NAME = "example.name"; + + /** + * The {@link Properties} key to specify the file for the example. KEY_FILE_NAME by default + */ + public static final String KEY_FILE = "example.file"; + + /** + * The {@link Properties} key to specify the proof file in the tree. May be left open + */ + public static final String KEY_PROOF_FILE = "example.proofFile"; + + /** + * The {@link Properties} key to specify the path in the tree. Prefix to specify additional + * files to load. Append 1, 2, 3, ... + */ + public static final String ADDITIONAL_FILE_PREFIX = "example.additionalFile."; + + /** + * The {@link Properties} key to specify the path in the tree. Prefix to specify export + * files which are not shown as tabs in the example wizard but are extracted to Java + * projects in the Eclipse integration. Append 1, 2, 3, ... + */ + public static final String EXPORT_FILE_PREFIX = "example.exportFile."; + + public final File exampleFile; + public final File directory; + public final String description; + public final Properties properties; + + public Example(File file) throws IOException { + this.exampleFile = file; + this.directory = file.getParentFile(); + this.properties = new Properties(); + StringBuilder sb = new StringBuilder(); + extractDescription(file, sb, properties); + this.description = sb.toString(); + } + + public File getDirectory() { + return directory; + } + + public File getProofFile() { + return new File(directory, properties.getProperty(KEY_PROOF_FILE, PROOF_FILE_NAME)); + } + + public File getObligationFile() { + return new File(directory, properties.getProperty(KEY_FILE, KEY_FILE_NAME)); + } + + public String getName() { + return properties.getProperty(KEY_NAME, directory.getName()); + } + + public String getDescription() { + return description; + } + + public File getExampleFile() { + return exampleFile; + } + + public List getAdditionalFiles() { + var result = new ArrayList(); + int i = 1; + while (properties.containsKey(ADDITIONAL_FILE_PREFIX + i)) { + result.add(new File(directory, properties.getProperty(ADDITIONAL_FILE_PREFIX + i))); + i++; + } + return result; + } + + public List getExportFiles() { + ArrayList result = new ArrayList<>(); + int i = 1; + while (properties.containsKey(EXPORT_FILE_PREFIX + i)) { + result.add(new File(directory, properties.getProperty(EXPORT_FILE_PREFIX + i))); + i++; + } + return result; + } + + public String[] getPath() { + return properties.getProperty(KEY_PATH, DEFAULT_CATEGORY_PATH).split("/"); + } + + @Override + public String toString() { + return getName(); + } + + public void addToTreeModel(DefaultTreeModel model) { + DefaultMutableTreeNode node = + findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); + node.add(new DefaultMutableTreeNode(this)); + } + + private DefaultMutableTreeNode findChild(DefaultMutableTreeNode root, String[] path, + int from) { + if (from == path.length) { + return root; + } + Enumeration en = root.children(); + while (en.hasMoreElements()) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) en.nextElement(); + if (node.getUserObject().equals(path[from])) { + return findChild(node, path, from + 1); + } + } + // not found ==> add new + DefaultMutableTreeNode node = new DefaultMutableTreeNode(path[from]); + root.add(node); + return findChild(node, path, from + 1); + } + + public boolean hasProof() { + return properties.containsKey(KEY_PROOF_FILE); + } + + private static StringBuilder extractDescription(File file, StringBuilder sb, + Properties properties) { + try (BufferedReader r = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) { + String line; + boolean emptyLineSeen = false; + while ((line = r.readLine()) != null) { + if (emptyLineSeen) { + sb.append(line).append("\n"); + } else { + String trimmed = line.trim(); + if (trimmed.length() == 0) { + emptyLineSeen = true; + } else if (trimmed.startsWith("#")) { + // ignore + } else { + String[] entry = trimmed.split(" *[:=] *", 2); + if (entry.length > 1) { + properties.put(entry[0], entry[1]); + } + } + } + } + } catch (IOException e) { + LOGGER.error("", e); + return sb; + } + return sb; + } +} \ No newline at end of file diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java index f4ee4884408..e37603b344e 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java @@ -37,15 +37,6 @@ public final class ExampleChooser extends JDialog { */ public static final String EXAMPLES_PATH = "examples"; - private static final long serialVersionUID = -4405666868752394532L; - - /** - * This constant is accessed by the eclipse based projects. - */ - public static final String KEY_FILE_NAME = "project.key"; - - private static final String PROOF_FILE_NAME = "project.proof"; - /** * Java property name to specify a custom key example folder. */ @@ -75,149 +66,7 @@ public final class ExampleChooser extends JDialog { */ private Example selectedExample; - /** - * This class wraps a {@link File} and has a special {@link #toString()} method only using the - * short file name w/o path. - *

    - * Used for displaying files in the examples list w/o prefix - */ - public static class Example { - /** - * The default category under which examples range if they do not have {@link #KEY_PATH} - * set. - */ - private static final String DEFAULT_CATEGORY_PATH = "Unsorted"; - - /** - * The {@link Properties} key to specify the path in the tree. - */ - private static final String KEY_PATH = "example.path"; - - /** - * The {@link Properties} key to specify the name of the example. Directory name if left - * open. - */ - private static final String KEY_NAME = "example.name"; - - /** - * The {@link Properties} key to specify the file for the example. KEY_FILE_NAME by default - */ - private static final String KEY_FILE = "example.file"; - - /** - * The {@link Properties} key to specify the proof file in the tree. May be left open - */ - private static final String KEY_PROOF_FILE = "example.proofFile"; - - /** - * The {@link Properties} key to specify the path in the tree. Prefix to specify additional - * files to load. Append 1, 2, 3, ... - */ - private static final String ADDITIONAL_FILE_PREFIX = "example.additionalFile."; - - /** - * The {@link Properties} key to specify the path in the tree. Prefix to specify export - * files which are not shown as tabs in the example wizard but are extracted to Java - * projects in the Eclipse integration. Append 1, 2, 3, ... - */ - private static final String EXPORT_FILE_PREFIX = "example.exportFile."; - - private final File exampleFile; - private final File directory; - private final String description; - private final Properties properties; - - public Example(File file) throws IOException { - this.exampleFile = file; - this.directory = file.getParentFile(); - this.properties = new Properties(); - StringBuilder sb = new StringBuilder(); - extractDescription(file, sb, properties); - this.description = sb.toString(); - } - - public File getDirectory() { - return directory; - } - public File getProofFile() { - return new File(directory, properties.getProperty(KEY_PROOF_FILE, PROOF_FILE_NAME)); - } - - public File getObligationFile() { - return new File(directory, properties.getProperty(KEY_FILE, KEY_FILE_NAME)); - } - - public String getName() { - return properties.getProperty(KEY_NAME, directory.getName()); - } - - public String getDescription() { - return description; - } - - public File getExampleFile() { - return exampleFile; - } - - public List getAdditionalFiles() { - ArrayList result = new ArrayList<>(); - int i = 1; - while (properties.containsKey(ADDITIONAL_FILE_PREFIX + i)) { - result.add(new File(directory, properties.getProperty(ADDITIONAL_FILE_PREFIX + i))); - i++; - } - return result; - } - - public List getExportFiles() { - ArrayList result = new ArrayList<>(); - int i = 1; - while (properties.containsKey(EXPORT_FILE_PREFIX + i)) { - result.add(new File(directory, properties.getProperty(EXPORT_FILE_PREFIX + i))); - i++; - } - return result; - } - - public String[] getPath() { - return properties.getProperty(KEY_PATH, DEFAULT_CATEGORY_PATH).split("/"); - } - - @Override - public String toString() { - return getName(); - } - - public void addToTreeModel(DefaultTreeModel model) { - DefaultMutableTreeNode node = - findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); - node.add(new DefaultMutableTreeNode(this)); - } - - private DefaultMutableTreeNode findChild(DefaultMutableTreeNode root, String[] path, - int from) { - if (from == path.length) { - return root; - } - Enumeration en = root.children(); - while (en.hasMoreElements()) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode) en.nextElement(); - if (node.getUserObject().equals(path[from])) { - return findChild(node, path, from + 1); - } - } - // not found ==> add new - DefaultMutableTreeNode node = new DefaultMutableTreeNode(path[from]); - root.add(node); - return findChild(node, path, from + 1); - } - - public boolean hasProof() { - return properties.containsKey(KEY_PROOF_FILE); - } - - } // ------------------------------------------------------------------------- // constructors @@ -352,34 +201,6 @@ private static String fileAsString(File f) { } } - private static StringBuilder extractDescription(File file, StringBuilder sb, - Properties properties) { - try (BufferedReader r = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) { - String line; - boolean emptyLineSeen = false; - while ((line = r.readLine()) != null) { - if (emptyLineSeen) { - sb.append(line).append("\n"); - } else { - String trimmed = line.trim(); - if (trimmed.length() == 0) { - emptyLineSeen = true; - } else if (trimmed.startsWith("#")) { - // ignore - } else { - String[] entry = trimmed.split(" *[:=] *", 2); - if (entry.length > 1) { - properties.put(entry[0], entry[1]); - } - } - } - } - } catch (IOException e) { - LOGGER.error("", e); - return sb; - } - return sb; - } private void updateDescription() { diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle new file mode 100644 index 00000000000..463b7dbc11a --- /dev/null +++ b/keyext.api/build.gradle @@ -0,0 +1,6 @@ +dependencies { + implementation(project(":key.core")) + implementation(project(":key.ui")) + + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java b/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java new file mode 100644 index 00000000000..67240012e90 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java @@ -0,0 +1,20 @@ +package org.keyproject.key; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.File; +import java.io.IOException; + +public class FileTypeAdapter extends TypeAdapter { + @Override + public void write(JsonWriter out, File value) throws IOException { + out.value(value.toString()); + } + + @Override + public File read(JsonReader in) throws IOException { + return new File(in.nextString()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java new file mode 100644 index 00000000000..76c2d1eefdd --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java @@ -0,0 +1,58 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.gui.Example; +import de.uka.ilkd.key.gui.ExampleChooser; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public interface KeyApi extends KeyExampleApi, KeyMetaApi { + //region general server management + /** + * Shutdown Request (:leftwards_arrow_with_hook:) + The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. + + If a server receives requests after a shutdown request those requests should error with InvalidRequest. + + Request: + + method: ‘shutdown’ + params: none + Response: + + result: null + error: code and message set in case an exception happens during shutdown request. + */ + @JsonRequest + Void shutdown(); + + /** + * Exit Notification (:arrow_right:) + * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. + *

    + * Notification: + *

    + * method: ‘exit’ + * params: none + */ + @JsonNotification + void exit(); + + + + interface SetTraceParams { + /** + * The new value that should be assigned to the trace setting. + */ + TraceValue value = null; + } + /** + * SetTrace Notification + * A notification that should be used by the client to modify the trace setting of the server. + */ + @JsonNotification + void setTrace(SetTraceParams params); + //endregion +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java new file mode 100644 index 00000000000..0a967998dac --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java @@ -0,0 +1,56 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.api.KeYApi; +import de.uka.ilkd.key.gui.Example; +import de.uka.ilkd.key.gui.ExampleChooser; +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import de.uka.ilkd.key.util.KeYConstants; +import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@JsonSegment +class KeyApiImpl implements KeyApi { + @Override + @JsonRequest + public CompletableFuture> examples() { + return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); + } + + @Override + public Void shutdown() { + return null; + } + + @Override + public void exit() { + + } + + @Override + public void setTrace(SetTraceParams params) { + + } + + @Override + public CompletableFuture getVersion() { + return CompletableFuture.completedFuture(KeYConstants.VERSION); + } + + @Override + public CompletableFuture> getAvailableMacros() { + return CompletableFuture.completedFuture( + KeYApi.getMacroApi().getMacros().stream().map(MacroDescription::from) + .toList() + ); + } + + @Override + public CompletableFuture>> getAvailableScriptCommands() { + return CompletableFuture.completedFuture( + KeYApi.getScriptCommandApi().getScriptCommands().stream().toList()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java new file mode 100644 index 00000000000..f1fe80a6dfc --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java @@ -0,0 +1,14 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.gui.Example; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@JsonSegment("examples") +public interface KeyExampleApi { + @JsonRequest("list") + CompletableFuture> examples(); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java new file mode 100644 index 00000000000..e5538b30896 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java @@ -0,0 +1,21 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@JsonSegment("meta") +public interface KeyMetaApi { + @JsonRequest + CompletableFuture getVersion(); + + @JsonRequest + CompletableFuture> getAvailableMacros(); + + @JsonRequest + CompletableFuture>> getAvailableScriptCommands(); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java new file mode 100644 index 00000000000..2f34d3e03ed --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java @@ -0,0 +1,9 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.macros.ProofMacro; + +public record MacroDescription(String name, String description, String category) { + public static MacroDescription from(ProofMacro m) { + return new MacroDescription(m.getName(), m.getDescription(), m.getCategory()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java new file mode 100644 index 00000000000..127b36a702c --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java @@ -0,0 +1,63 @@ +package org.keyproject.key.remoteapi; + +import com.google.gson.GsonBuilder; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.keyproject.key.FileTypeAdapter; +import org.keyproject.key.remoteclient.ClientApi; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class Main { + public static void main(String[] args) throws ExecutionException, InterruptedException { + var future = launch(System.out, System.in); + future.startListening(); + } + + public static Launcher launch(OutputStream out, InputStream in) { + var localServices = getLocalServices(); + var remoteInterfaces = getRemoteInterfaces(); + var launcherBuilder = new Launcher.Builder() + .setOutput(out) + .setInput(in) + .traceMessages(new PrintWriter(System.err)) + .validateMessages(true); + + launcherBuilder.configureGson(Main::configureJson); + + //if (localServices != null && !localServices.isEmpty()) + launcherBuilder.setLocalService(new KeyApiImpl()); + //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) + launcherBuilder.setRemoteInterface(ClientApi.class); + + var launcher = launcherBuilder.create(); + return launcher; + } + + public static void configureJson(GsonBuilder gsonBuilder) { + gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); + } + + private static Collection> getRemoteInterfaces() { + return Collections.singleton(ClientApi.class); + /* return ServiceLoader.load(ClientService.class) + .stream() + .map(ServiceLoader.Provider::type) + .collect(Collectors.toSet()); + */ + } + + private static List getLocalServices() { + return Collections.singletonList(new KeyApiImpl()); + /*return ServiceLoader.load(KeyService.class) + .stream().map(ServiceLoader.Provider::get) + .map(it -> (Object) it) + .toList();*/ + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java new file mode 100644 index 00000000000..65db8662e4e --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java @@ -0,0 +1,4 @@ +package org.keyproject.key.remoteapi; + +public record ProofId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java new file mode 100644 index 00000000000..7e99ffd0cf5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java @@ -0,0 +1,67 @@ +package org.keyproject.key.remoteapi; + +import de.uka.ilkd.key.api.ProofManagementApi; +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.io.File; +import java.util.List; + +@JsonSegment +public interface ProofLoading { + @JsonRequest ProofId loadExample(String id); + + interface LoadParams { + File keyFile; + File javaFile; + + List classPath, + File bootClassPath, List includes + } + + /** + * @param keyFile + * @return + * @throws ProblemLoaderException + */ + @JsonRequest ProofId loadFromKeyFile(File keyFile) throws ProblemLoaderException { + return new ProofManagementApi(KeYEnvironment.load(keyFile)); + } + + /** + * @param location + * @param classPath + * @param bootClassPath + * @param includes + * @return + * @throws ProblemLoaderException + */ + @JsonRequest ProofId loadProof(File location, List classPath, + File bootClassPath, List includes) throws ProblemLoaderException { + return new ProofManagementApi( + KeYEnvironment.load(location, classPath, bootClassPath, includes)); + } + + /** + * @param javaSourceCode + * @return + * @throws ProblemLoaderException + */ + @JsonRequest ProofId loadProof(File javaSourceCode) throws ProblemLoaderException { + return loadProof(javaSourceCode, null, null, null); + } + + /** + * Load a proof file, creates a KeY environment that can be accessed with other methods from + * this facade + * + * @param file Path to the source code folder/file or to a *.proof file + * @param classPaths Optionally: Additional specifications for API classes + * @param bootClassPath Optionally: Different default specifications for Java API + * @param includes Optionally: Additional includes to consider + */ + @JsonRequest ProofId loadProofFile(File file, List classPaths, File bootClassPath, + List includes); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java new file mode 100644 index 00000000000..1d1d4859e57 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java @@ -0,0 +1,5 @@ +package org.keyproject.key.remoteapi; + +public enum TraceValue { + Off, Message, All; +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java new file mode 100644 index 00000000000..4fd0b792189 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java @@ -0,0 +1,53 @@ +package org.keyproject.key.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; +import org.keyproject.key.remoteapi.Main; +import org.keyproject.key.remoteapi.KeyApi; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.concurrent.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Client { + public static void main(String[] args) throws IOException, ExecutionException, InterruptedException, TimeoutException { + PipedInputStream inClient = new PipedInputStream(); + PipedOutputStream outClient = new PipedOutputStream(); + PipedInputStream inServer = new PipedInputStream(); + PipedOutputStream outServer = new PipedOutputStream(); + + inClient.connect(outServer); + outClient.connect(inServer); + + Launcher serverLauncher = Main.launch(outServer, inServer); + + var client = new SimpleClient(); + Launcher clientLauncher = new Launcher.Builder() + .setLocalService(client) + .setRemoteInterfaces(Collections.singleton(KeyApi.class)) + .setInput(inClient) + .setOutput(outClient) + .configureGson(Main::configureJson) + .traceMessages(new PrintWriter(System.err)) + .create(); + + Logger logger = Logger.getLogger(StreamMessageProducer.class.getName()); + logger.setLevel(Level.SEVERE); + + var clientListening = clientLauncher.startListening(); + var serverListening = serverLauncher.startListening(); + + //clientLauncher.getRemoteProxy().examples(); + serverLauncher.getRemoteProxy().sayHello("Alex"); + + serverListening.get(1, TimeUnit.SECONDS); + clientListening.get(1, TimeUnit.SECONDS); + } +} + + diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java new file mode 100644 index 00000000000..23c3ddf9e39 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java @@ -0,0 +1,224 @@ +package org.keyproject.key.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.eclipse.lsp4j.jsonrpc.validation.NonNull; + +import javax.annotation.Nullable; + +@JsonSegment +public interface ClientApi { + @JsonNotification + void sayHello(String e); + + /** + * LogTrace Notification (:arrow_left:) + * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. + *

    + * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. + *

    + * Notification: + *

    + * method: ‘$/logTrace’ + * params: LogTraceParams defined as follows: + */ + @JsonNotification + void logTrace(LogTraceParams params); + + interface LogTraceParams { + /** + * The message to be logged. + */ + @NonNull + String message = null; + /** + * Additional information that can be computed if the `trace` configuration + * is set to `'verbose'` + */ + String verbose = null; + } + + //region Window + + /** + * ShowMessage Notification (:arrow_left:) + * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. + *

    + * Notification: + *

    + * method: ‘window/showMessage’ + * params: ShowMessageParams defined as follows: + */ + @JsonNotification + public void ShowMessage(ShowMessageParams params); + + interface ShowMessageParams { + /** + * The message type. See {@link MessageType}. + */ + MessageType type = null; + + /** + * The actual message. + */ + String message = null; + } + + enum MessageType { + + Unused, + /** + * An error message. + */ + Error, + /** + * A warning message. + */ + Warning, + /** + * An information message. + */ + Info, + /** + * A log message. + */ + Log, + /** + * A debug message. + * + * @proposed + * @since 3.18.0 + */ + Debug + } + + /** + * ShowMessage Request (:arrow_right_hook:) + * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. + */ + @JsonRequest + @Nullable + MessageActionItem ShowMessage(ShowMessageRequestParams params); + + interface ShowMessageRequestParams { + /** + * The message type. See {@link MessageType} + */ + MessageType type = null; + + /** + * The actual message + */ + String message = null; + + /** + * The message action items to present. + */ + MessageActionItem[] actions = new MessageActionItem[0]; + } + + interface MessageActionItem { + /** + * A short title like 'Retry', 'Open Log' etc. + */ + String title = null; + } + + /** + * Show Document Request (:arrow_right_hook:) + * New in version 3.16.0 + *

    + * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. + *

    + * property path (optional): window.showDocument + * property type: ShowDocumentClientCapabilities defined as follows: + */ + @JsonRequest + ShowDocumentResult showDocument(ShowDocumentParams params); + + interface ShowDocumentParams { + /** + * The uri to show. + */ + String uri; + + /** + * Indicates to show the resource in an external program. + * To show, for example, `https://code.visualstudio.com/` + * in the default WEB browser set `external` to `true`. + */ + Boolean external; + + /** + * An optional property to indicate whether the editor + * showing the document should take focus or not. + * Clients might ignore this property if an external + * program is started. + */ + Boolean takeFocus; + + /** + * An optional selection range if the document is a text + * document. Clients might ignore the property if an + * external program is started or the file is not a text + * file. + */ + Range selection; + } + + defined + + interface ShowDocumentResult { + /** + * A boolean indicating if the show was successful. + */ + boolean success; + } + + /** + * LogMessage Notification(:arrow_left:) + *

    + * The log message notification is sent from the server to the client to ask the client to log + * a particular message. + */ + interface LogMessageParams { + /** + * The message type. See {@link MessageType} + */ + MessageType type; + + /** + * The actual message + */ + String message; + } + + /** + Create Work + + Done Progress(:arrow_right_hook:) + + The window/workDoneProgress/ create request is sent from the server to the client to ask + the clie nt to create a work done progress. + */ + + interface WorkDoneProgressCreateParams { + /** + * The token to be used to report progress. + */ + ProgressToken token; + } + + @JsonNotification workDoneProgressCancel(); + WorkDoneProgressCancelParams defined + interface WorkDoneProgressCancelParams { + /** + * The token to be used to report progress. + */ + ProgressToken token; + } + + + //endregion +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java new file mode 100644 index 00000000000..9578fb8b171 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java @@ -0,0 +1,9 @@ +package org.keyproject.key.remoteclient; + +class SimpleClient implements ClientApi { + + @Override + public void sayHello(String e) { + System.out.format("Hello, %s%n", e); + } +} diff --git a/settings.gradle b/settings.gradle index e71fc368308..a7fccaa51b6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,3 +13,5 @@ include 'keyext.ui.testgen' include 'keyext.proofmanagement' include 'keyext.exploration' include 'keyext.slicing' + +include 'keyext.api' From 6623b4b31064a45c111c27a3390c17601afd094d Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 8 Oct 2023 13:43:38 +0200 Subject: [PATCH 11/50] different clients --- keyext.api/build.gradle | 24 +- .../key/{ => api}/FileTypeAdapter.java | 2 +- .../key/{ => api}/remoteapi/KeyApi.java | 7 +- .../key/{ => api}/remoteapi/KeyApiImpl.java | 8 +- .../{ => api}/remoteapi/KeyExampleApi.java | 2 +- .../key/{ => api}/remoteapi/KeyMetaApi.java | 3 +- .../{ => api}/remoteapi/MacroDescription.java | 2 +- .../keyproject/key/api/remoteapi/ProofId.java | 4 + .../key/api/remoteapi/ProofLoading.java | 19 ++ .../key/{ => api}/remoteapi/TraceValue.java | 2 +- .../key/api/remoteclient/ClientApi.java | 65 +++++ .../org/keyproject/key/remoteapi/Main.java | 63 ----- .../org/keyproject/key/remoteapi/ProofId.java | 4 - .../key/remoteapi/ProofLoading.java | 67 ------ .../key/remoteclient/ClientApi.java | 224 ------------------ .../key/remoteclient/SimpleClient.java | 9 - keyext.api/src/main/python/keyapi/__init__.py | 17 ++ .../java/org/keyproject/key/api}/Client.java | 16 +- .../org/keyproject/key/api/SimpleClient.java | 35 +++ 19 files changed, 182 insertions(+), 391 deletions(-) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/FileTypeAdapter.java (93%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyApi.java (92%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyApiImpl.java (88%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyExampleApi.java (89%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/KeyMetaApi.java (85%) rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/MacroDescription.java (86%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java rename keyext.api/src/main/java/org/keyproject/key/{ => api}/remoteapi/TraceValue.java (54%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java create mode 100644 keyext.api/src/main/python/keyapi/__init__.py rename keyext.api/src/{main/java/org/keyproject/key/remoteclient => test/java/org/keyproject/key/api}/Client.java (80%) create mode 100644 keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index 463b7dbc11a..0f3b2743c24 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -1,6 +1,28 @@ +plugins { + id 'application' + + // Used to create a single executable jar file with all dependencies + // see task "shadowJar" below + // https://imperceptiblethoughts.com/shadow/ + id 'com.github.johnrengelman.shadow' version "8.1.1" +} + +description "Verification server interface via JSON-RPC" + dependencies { implementation(project(":key.core")) implementation(project(":key.ui")) implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") -} \ No newline at end of file + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") + implementation("org.eclipse.jetty.websocket:websocket-javax-server:10.0.16") + implementation("info.picocli:picocli:4.7.5") + //for GraalVM annotationProcessor 'info.picocli:picocli-codegen:4.7.5' +} + + +compileJava { + // for GraalVM options.compilerArgs += ["-Aproject=${project.group}/${project.name}"] +} + diff --git a/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java similarity index 93% rename from keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java rename to keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java index 67240012e90..9c03fdfae41 100644 --- a/keyext.api/src/main/java/org/keyproject/key/FileTypeAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java @@ -1,4 +1,4 @@ -package org.keyproject.key; +package org.keyproject.key.api; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java similarity index 92% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index 76c2d1eefdd..9a6e35fe2eb 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -1,11 +1,8 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.gui.Example; -import de.uka.ilkd.key.gui.ExampleChooser; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import java.util.List; import java.util.concurrent.CompletableFuture; public interface KeyApi extends KeyExampleApi, KeyMetaApi { @@ -26,7 +23,7 @@ The shutdown request is sent from the client to the server. It asks the server t error: code and message set in case an exception happens during shutdown request. */ @JsonRequest - Void shutdown(); + CompletableFuture shutdown(); /** * Exit Notification (:arrow_right:) diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java similarity index 88% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java index 0a967998dac..33ae9c03aba 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.api.KeYApi; import de.uka.ilkd.key.gui.Example; @@ -13,7 +13,7 @@ import java.util.concurrent.CompletableFuture; @JsonSegment -class KeyApiImpl implements KeyApi { +public class KeyApiImpl implements KeyApi { @Override @JsonRequest public CompletableFuture> examples() { @@ -21,8 +21,8 @@ public CompletableFuture> examples() { } @Override - public Void shutdown() { - return null; + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(null); } @Override diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java similarity index 89% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java index f1fe80a6dfc..b1bc064b954 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.gui.Example; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java similarity index 85% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java index e5538b30896..df0112c51f2 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/KeyMetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java @@ -1,7 +1,6 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; -import org.eclipse.lsp4j.jsonrpc.CompletableFutures; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java similarity index 86% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java index 2f34d3e03ed..ad6d12babf8 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/MacroDescription.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.macros.ProofMacro; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java new file mode 100644 index 00000000000..7d1d4eb5d6b --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java @@ -0,0 +1,4 @@ +package org.keyproject.key.api.remoteapi; + +public record ProofId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java new file mode 100644 index 00000000000..49081037dc0 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java @@ -0,0 +1,19 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +@JsonSegment +public interface ProofLoading { + @JsonRequest + ProofId loadExample(String id); + + /** + * @param params + * @return + * @throws ProblemLoaderException + */ + @JsonRequest + EnvId load(LoadParams params) throws ProblemLoaderException; +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java similarity index 54% rename from keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java index 1d1d4859e57..567b740d6d8 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/TraceValue.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java @@ -1,4 +1,4 @@ -package org.keyproject.key.remoteapi; +package org.keyproject.key.api.remoteapi; public enum TraceValue { Off, Message, All; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java new file mode 100644 index 00000000000..6f02b10a186 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -0,0 +1,65 @@ +package org.keyproject.key.api.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import javax.annotation.Nullable; +import java.util.concurrent.CompletableFuture; + +@JsonSegment +public interface ClientApi { + @JsonNotification + void sayHello(String e); + + /** + * LogTrace Notification (:arrow_left:) + * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. + *

    + * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. + *

    + * Notification: + *

    + * method: ‘$/logTrace’ + * params: LogTraceParams defined as follows: + */ + @JsonNotification + void logTrace(LogTraceParams params); + //region Window + + /** + * ShowMessage Notification (:arrow_left:) + * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. + *

    + * Notification: + *

    + * method: ‘window/showMessage’ + * params: ShowMessageParams defined as follows: + */ + @JsonNotification("sm") + void showMessage(ShowMessageParams params); + + + + /** + * ShowMessage Request (:arrow_right_hook:) + * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. + */ + @JsonRequest + @Nullable + CompletableFuture userResponse(ShowMessageRequestParams params); + + + /** + * Show Document Request (:arrow_right_hook:) + * New in version 3.16.0 + *

    + * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. + *

    + * property path (optional): window.showDocument + * property type: ShowDocumentClientCapabilities defined as follows: + */ + @JsonRequest + CompletableFuture showDocument(ShowDocumentParams params); + //endregion +} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java deleted file mode 100644 index 127b36a702c..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/Main.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.keyproject.key.remoteapi; - -import com.google.gson.GsonBuilder; -import org.eclipse.lsp4j.jsonrpc.Launcher; -import org.keyproject.key.FileTypeAdapter; -import org.keyproject.key.remoteclient.ClientApi; - -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ExecutionException; - -public class Main { - public static void main(String[] args) throws ExecutionException, InterruptedException { - var future = launch(System.out, System.in); - future.startListening(); - } - - public static Launcher launch(OutputStream out, InputStream in) { - var localServices = getLocalServices(); - var remoteInterfaces = getRemoteInterfaces(); - var launcherBuilder = new Launcher.Builder() - .setOutput(out) - .setInput(in) - .traceMessages(new PrintWriter(System.err)) - .validateMessages(true); - - launcherBuilder.configureGson(Main::configureJson); - - //if (localServices != null && !localServices.isEmpty()) - launcherBuilder.setLocalService(new KeyApiImpl()); - //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) - launcherBuilder.setRemoteInterface(ClientApi.class); - - var launcher = launcherBuilder.create(); - return launcher; - } - - public static void configureJson(GsonBuilder gsonBuilder) { - gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); - } - - private static Collection> getRemoteInterfaces() { - return Collections.singleton(ClientApi.class); - /* return ServiceLoader.load(ClientService.class) - .stream() - .map(ServiceLoader.Provider::type) - .collect(Collectors.toSet()); - */ - } - - private static List getLocalServices() { - return Collections.singletonList(new KeyApiImpl()); - /*return ServiceLoader.load(KeyService.class) - .stream().map(ServiceLoader.Provider::get) - .map(it -> (Object) it) - .toList();*/ - } -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java deleted file mode 100644 index 65db8662e4e..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofId.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.keyproject.key.remoteapi; - -public record ProofId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java deleted file mode 100644 index 7e99ffd0cf5..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteapi/ProofLoading.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.keyproject.key.remoteapi; - -import de.uka.ilkd.key.api.ProofManagementApi; -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.io.ProblemLoaderException; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - -import java.io.File; -import java.util.List; - -@JsonSegment -public interface ProofLoading { - @JsonRequest ProofId loadExample(String id); - - interface LoadParams { - File keyFile; - File javaFile; - - List classPath, - File bootClassPath, List includes - } - - /** - * @param keyFile - * @return - * @throws ProblemLoaderException - */ - @JsonRequest ProofId loadFromKeyFile(File keyFile) throws ProblemLoaderException { - return new ProofManagementApi(KeYEnvironment.load(keyFile)); - } - - /** - * @param location - * @param classPath - * @param bootClassPath - * @param includes - * @return - * @throws ProblemLoaderException - */ - @JsonRequest ProofId loadProof(File location, List classPath, - File bootClassPath, List includes) throws ProblemLoaderException { - return new ProofManagementApi( - KeYEnvironment.load(location, classPath, bootClassPath, includes)); - } - - /** - * @param javaSourceCode - * @return - * @throws ProblemLoaderException - */ - @JsonRequest ProofId loadProof(File javaSourceCode) throws ProblemLoaderException { - return loadProof(javaSourceCode, null, null, null); - } - - /** - * Load a proof file, creates a KeY environment that can be accessed with other methods from - * this facade - * - * @param file Path to the source code folder/file or to a *.proof file - * @param classPaths Optionally: Additional specifications for API classes - * @param bootClassPath Optionally: Different default specifications for Java API - * @param includes Optionally: Additional includes to consider - */ - @JsonRequest ProofId loadProofFile(File file, List classPaths, File bootClassPath, - List includes); -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java deleted file mode 100644 index 23c3ddf9e39..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteclient/ClientApi.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.keyproject.key.remoteclient; - -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.eclipse.lsp4j.jsonrpc.validation.NonNull; - -import javax.annotation.Nullable; - -@JsonSegment -public interface ClientApi { - @JsonNotification - void sayHello(String e); - - /** - * LogTrace Notification (:arrow_left:) - * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. - *

    - * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. - *

    - * Notification: - *

    - * method: ‘$/logTrace’ - * params: LogTraceParams defined as follows: - */ - @JsonNotification - void logTrace(LogTraceParams params); - - interface LogTraceParams { - /** - * The message to be logged. - */ - @NonNull - String message = null; - /** - * Additional information that can be computed if the `trace` configuration - * is set to `'verbose'` - */ - String verbose = null; - } - - //region Window - - /** - * ShowMessage Notification (:arrow_left:) - * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. - *

    - * Notification: - *

    - * method: ‘window/showMessage’ - * params: ShowMessageParams defined as follows: - */ - @JsonNotification - public void ShowMessage(ShowMessageParams params); - - interface ShowMessageParams { - /** - * The message type. See {@link MessageType}. - */ - MessageType type = null; - - /** - * The actual message. - */ - String message = null; - } - - enum MessageType { - - Unused, - /** - * An error message. - */ - Error, - /** - * A warning message. - */ - Warning, - /** - * An information message. - */ - Info, - /** - * A log message. - */ - Log, - /** - * A debug message. - * - * @proposed - * @since 3.18.0 - */ - Debug - } - - /** - * ShowMessage Request (:arrow_right_hook:) - * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. - */ - @JsonRequest - @Nullable - MessageActionItem ShowMessage(ShowMessageRequestParams params); - - interface ShowMessageRequestParams { - /** - * The message type. See {@link MessageType} - */ - MessageType type = null; - - /** - * The actual message - */ - String message = null; - - /** - * The message action items to present. - */ - MessageActionItem[] actions = new MessageActionItem[0]; - } - - interface MessageActionItem { - /** - * A short title like 'Retry', 'Open Log' etc. - */ - String title = null; - } - - /** - * Show Document Request (:arrow_right_hook:) - * New in version 3.16.0 - *

    - * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. - *

    - * property path (optional): window.showDocument - * property type: ShowDocumentClientCapabilities defined as follows: - */ - @JsonRequest - ShowDocumentResult showDocument(ShowDocumentParams params); - - interface ShowDocumentParams { - /** - * The uri to show. - */ - String uri; - - /** - * Indicates to show the resource in an external program. - * To show, for example, `https://code.visualstudio.com/` - * in the default WEB browser set `external` to `true`. - */ - Boolean external; - - /** - * An optional property to indicate whether the editor - * showing the document should take focus or not. - * Clients might ignore this property if an external - * program is started. - */ - Boolean takeFocus; - - /** - * An optional selection range if the document is a text - * document. Clients might ignore the property if an - * external program is started or the file is not a text - * file. - */ - Range selection; - } - - defined - - interface ShowDocumentResult { - /** - * A boolean indicating if the show was successful. - */ - boolean success; - } - - /** - * LogMessage Notification(:arrow_left:) - *

    - * The log message notification is sent from the server to the client to ask the client to log - * a particular message. - */ - interface LogMessageParams { - /** - * The message type. See {@link MessageType} - */ - MessageType type; - - /** - * The actual message - */ - String message; - } - - /** - Create Work - - Done Progress(:arrow_right_hook:) - - The window/workDoneProgress/ create request is sent from the server to the client to ask - the clie nt to create a work done progress. - */ - - interface WorkDoneProgressCreateParams { - /** - * The token to be used to report progress. - */ - ProgressToken token; - } - - @JsonNotification workDoneProgressCancel(); - WorkDoneProgressCancelParams defined - interface WorkDoneProgressCancelParams { - /** - * The token to be used to report progress. - */ - ProgressToken token; - } - - - //endregion -} diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java b/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java deleted file mode 100644 index 9578fb8b171..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/remoteclient/SimpleClient.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.keyproject.key.remoteclient; - -class SimpleClient implements ClientApi { - - @Override - public void sayHello(String e) { - System.out.format("Hello, %s%n", e); - } -} diff --git a/keyext.api/src/main/python/keyapi/__init__.py b/keyext.api/src/main/python/keyapi/__init__.py new file mode 100644 index 00000000000..8523f3801f5 --- /dev/null +++ b/keyext.api/src/main/python/keyapi/__init__.py @@ -0,0 +1,17 @@ +from keyapi.rpc import JsonRPCHandler, Client + + +class KeyClient(Client): + def __int__(self): + pass + + def handle(self, res): + print(res) + + +class KeyStub(JsonRPCHandler): + def __init__(self, input, output): + super().__init__(input, output) + + def list_examples(self): + return self._send("examples/list", []) diff --git a/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java b/keyext.api/src/test/java/org/keyproject/key/api/Client.java similarity index 80% rename from keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java rename to keyext.api/src/test/java/org/keyproject/key/api/Client.java index 4fd0b792189..4922de0993a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/remoteclient/Client.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/Client.java @@ -1,16 +1,18 @@ -package org.keyproject.key.remoteclient; +package org.keyproject.key.api; import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; -import org.keyproject.key.remoteapi.Main; -import org.keyproject.key.remoteapi.KeyApi; +import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteclient.ClientApi; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintWriter; import java.util.Collections; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,7 +26,7 @@ public static void main(String[] args) throws IOException, ExecutionException, I inClient.connect(outServer); outClient.connect(inServer); - Launcher serverLauncher = Main.launch(outServer, inServer); + Launcher serverLauncher = StartServer.launch(outServer, inServer); var client = new SimpleClient(); Launcher clientLauncher = new Launcher.Builder() @@ -32,7 +34,7 @@ public static void main(String[] args) throws IOException, ExecutionException, I .setRemoteInterfaces(Collections.singleton(KeyApi.class)) .setInput(inClient) .setOutput(outClient) - .configureGson(Main::configureJson) + .configureGson(StartServer::configureJson) .traceMessages(new PrintWriter(System.err)) .create(); @@ -49,5 +51,3 @@ public static void main(String[] args) throws IOException, ExecutionException, I clientListening.get(1, TimeUnit.SECONDS); } } - - diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java new file mode 100644 index 00000000000..3370f6eb31f --- /dev/null +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -0,0 +1,35 @@ +package org.keyproject.key.api; + +import org.keyproject.key.api.remoteclient.*; + +import javax.annotation.Nullable; +import java.util.concurrent.CompletableFuture; + +class SimpleClient implements ClientApi { + + @Override + public void sayHello(String e) { + System.out.format("Hello, %s%n", e); + } + + @Override + public void logTrace(LogTraceParams params) { + + } + + @Override + public void userResponse(ShowMessageParams params) { + + } + + @Nullable + @Override + public CompletableFuture userResponse(ShowMessageRequestParams params) { + return null; + } + + @Override + public CompletableFuture showDocument(ShowDocumentParams params) { + return null; + } +} From 5cbe177aefbb8390b60ee68cef657e0c71495ccd Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Fri, 13 Oct 2023 13:26:27 +0200 Subject: [PATCH 12/50] wip --- .../org/keyproject/key/api/StartServer.java | 203 ++++++++++++++++++ .../keyproject/key/api/remoteapi/EnvId.java | 8 + .../key/api/remoteapi/LoadParams.java | 8 + .../api/remoteclient/LogMessageParams.java | 15 ++ .../key/api/remoteclient/LogTraceParams.java | 19 ++ .../api/remoteclient/MessageActionItem.java | 9 + .../key/api/remoteclient/MessageType.java | 28 +++ .../api/remoteclient/ShowDocumentParams.java | 35 +++ .../api/remoteclient/ShowDocumentResult.java | 10 + .../api/remoteclient/ShowMessageParams.java | 14 ++ .../ShowMessageRequestParams.java | 20 ++ keyext.api/src/main/python/keyapi/rpc.py | 76 +++++++ keyext.api/src/main/python/main.py | 13 ++ 13 files changed, 458 insertions(+) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/StartServer.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java create mode 100644 keyext.api/src/main/python/keyapi/rpc.py create mode 100644 keyext.api/src/main/python/main.py diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java new file mode 100644 index 00000000000..26837bb84b6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -0,0 +1,203 @@ +package org.keyproject.key.api; + + +import com.google.gson.GsonBuilder; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.websocket.jakarta.WebSocketLauncherBuilder; +import org.keyproject.key.api.remoteapi.KeyApiImpl; +import org.keyproject.key.api.remoteclient.ClientApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; +import picocli.CommandLine.Option; + +import javax.annotation.Nullable; +import java.io.*; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @author Alexander Weigl + * @version 1 (07.10.23) + */ +@CommandLine.Command +public class StartServer implements Runnable { + private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); + + //region CLI arguments + @Option(names = "--std", description = "use stdout and stdin for communication") + boolean stdStreams; + @Option(names = "--trace", description = "use stdout and stdin for communication") + boolean enableTracing; + + @Option(names = "--server", paramLabel = "PORT", description = "enables the TCP server mode") + @Nullable + Integer serverPort; + + @Option(names = "--connectTo", paramLabel = "PORT", description = "enables the TCP client mode") + @Nullable + Integer clientPort; + + + @Option(names = "--infile", paramLabel = "FILE or PIPE", description = "read from named pipe or file") + @Nullable + File inFile; + + @Option(names = "--outfile", paramLabel = "FILE or PIPE", description = "write to named pipe or file") + File outFile; + + @Option(names = {"-h", "--help"}, usageHelp = true, description = "display a help message") + boolean helpRequested = false; + + @Option(names = "--websocket") + boolean websocket; + //endregion + + public static void main(String[] args) { + new CommandLine(new StartServer()).execute(args); + } + + private InputStream in; + private OutputStream out; + + private void establishStreams() throws IOException { + in = System.in; + out = System.out; + + if (stdStreams) { + return; + } + + if (clientPort != null) { + var socket = new Socket(InetAddress.getLocalHost(), clientPort); + socket.setKeepAlive(true); + socket.setTcpNoDelay(true); + in = socket.getInputStream(); + out = socket.getOutputStream(); + return; + } + + if (serverPort != null) { + var server = new ServerSocket(serverPort); + LOGGER.info("Waiting on port {}", serverPort); + var socket = server.accept(); + LOGGER.info("Connection to client established: {}", socket.getRemoteSocketAddress()); + socket.setKeepAlive(true); + socket.setTcpNoDelay(true); + in = socket.getInputStream(); + out = socket.getOutputStream(); + return; + } + + + if (inFile != null) { + in = new FileInputStream(inFile); + } + + if (outFile != null) { + out = new FileOutputStream(outFile); + } + + if (out == null || in == null) { + throw new IllegalStateException("Could not initialize the streams"); + } + } + + + @Override + public void run() { + if (helpRequested) { + return; + } + + /* + var server = new Server(); + var connector = new ServerConnector(); + server.addConnector(connector); + // Setup the basic application "context" for this application at "/" + // This is also known as the handler tree (in jetty speak) + var context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + server.setHandler(context); + + // Initialize javax.websocket layer + JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> + { + // Configure defaults for container + wsContainer.setDefaultMaxTextMessageBufferSize(65535); + + // Add WebSocket endpoint to javax.websocket layer + wsContainer.addEndpoint(WebSocketEndpoint.class); + });*/ + + + try { + if (websocket) { + var launcherBuilder = new WebSocketLauncherBuilder() + .setOutput(out) + .setInput(in) + .traceMessages(new PrintWriter(System.err)) + .validateMessages(true); + launcherBuilder.configureGson(StartServer::configureJson); + launcherBuilder.setLocalService(new KeyApiImpl()); + launcherBuilder.setRemoteInterface(ClientApi.class); + launcherBuilder.create().startListening().get(); + } else { + establishStreams(); + try (var lin = in; var lout = out) { + var listener = launch(lout, lin); + LOGGER.info("JSON-RPC is listening for requests"); + listener.startListening().get(); + } + } + } catch (IOException | InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + public static void configureJson(GsonBuilder gsonBuilder) { + gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); + } + + public static Launcher launch(OutputStream out, InputStream in) { + // var localServices = getLocalServices(); + // var remoteInterfaces = getRemoteInterfaces(); + var launcherBuilder = new Launcher.Builder() + .setOutput(out) + .setInput(in) + .traceMessages(new PrintWriter(System.err)) + .validateMessages(true); + + launcherBuilder.configureGson(StartServer::configureJson); + + //if (localServices != null && !localServices.isEmpty()) + launcherBuilder.setLocalService(new KeyApiImpl()); + //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) + launcherBuilder.setRemoteInterface(ClientApi.class); + + return launcherBuilder.create(); + } + + + private static Collection> getRemoteInterfaces() { + return Collections.singleton(ClientApi.class); + /* return ServiceLoader.load(ClientService.class) + .stream() + .map(ServiceLoader.Provider::type) + .collect(Collectors.toSet()); + */ + } + + private static List getLocalServices() { + return Collections.singletonList(new KeyApiImpl()); + /*return ServiceLoader.load(KeyService.class) + .stream().map(ServiceLoader.Provider::get) + .map(it -> (Object) it) + .toList();*/ + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java new file mode 100644 index 00000000000..3a2b5291d66 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.remoteapi; + +/** + * @author Alexander Weigl + * @version 1 (06.10.23) + */ +public record EnvId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java new file mode 100644 index 00000000000..7eadda846ba --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.remoteapi; + +import java.io.File; +import java.util.List; + +public record LoadParams(File keyFile, File javaFile, List classPath, File bootClassPath, List includes) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java new file mode 100644 index 00000000000..7ae00a584e7 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java @@ -0,0 +1,15 @@ +package org.keyproject.key.api.remoteclient; + +record LogMessageParams( + /** + * The message type. See {@link MessageType} + */ + MessageType type, + + /** + * The actual message + */ + String message +) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java new file mode 100644 index 00000000000..b5995ff5220 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java @@ -0,0 +1,19 @@ +package org.keyproject.key.api.remoteclient; + +import org.eclipse.lsp4j.jsonrpc.validation.NonNull; + +public record LogTraceParams( + /** + * The message to be logged. + */ + @NonNull + String messag, + + /** + * Additional information that can be computed if the `trace` configuration + * is set to `'verbose'` + */ + String verbose +) { + +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java new file mode 100644 index 00000000000..df586cac66d --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.remoteclient; + +public record MessageActionItem( + /** + * A short title like 'Retry', 'Open Log' etc. + */ + String title +) { +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java new file mode 100644 index 00000000000..cb8c20dd311 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java @@ -0,0 +1,28 @@ +package org.keyproject.key.api.remoteclient; + +public enum MessageType { + Unused, + /** + * An error message. + */ + Error, + /** + * A warning message. + */ + Warning, + /** + * An information message. + */ + Info, + /** + * A log message. + */ + Log, + /** + * A debug message. + * + * @proposed + * @since 3.18.0 + */ + Debug + } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java new file mode 100644 index 00000000000..17502b1a910 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java @@ -0,0 +1,35 @@ +package org.keyproject.key.api.remoteclient; + +import de.uka.ilkd.key.pp.Range; + +public record ShowDocumentParams( + /** + * The uri to show. + */ + String uri, + + /** + * Indicates to show the resource in an external program. + * To show, for example, `https://code.visualstudio.com/` + * in the default WEB browser set `external` to `true`. + */ + Boolean external, + + /** + * An optional property to indicate whether the editor + * showing the document should take focus or not. + * Clients might ignore this property if an external + * program is started. + */ + Boolean takeFocus, + + /** + * An optional selection range if the document is a text + * document. Clients might ignore the property if an + * external program is started or the file is not a text + * file. + */ + Range selection +) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java new file mode 100644 index 00000000000..b91a100858a --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api.remoteclient; + +public record ShowDocumentResult( + /** + * A boolean indicating if the show was successful. + */ + boolean success +) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java new file mode 100644 index 00000000000..9bf22a6f552 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java @@ -0,0 +1,14 @@ +package org.keyproject.key.api.remoteclient; + +public record ShowMessageParams( + /** + * The message type. See {@link MessageType}. + */ + MessageType type, + + /** + * The actual message. + */ + String message) { + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java new file mode 100644 index 00000000000..5e5f4f1410b --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java @@ -0,0 +1,20 @@ +package org.keyproject.key.api.remoteclient; + +public record ShowMessageRequestParams( + /** + * The message type. See {@link MessageType} + */ + MessageType type, + + /** + * The actual message + */ + String message, + + /** + * The message action items to present. + * + */ + MessageActionItem[] actions +) { +} \ No newline at end of file diff --git a/keyext.api/src/main/python/keyapi/rpc.py b/keyext.api/src/main/python/keyapi/rpc.py new file mode 100644 index 00000000000..89dc6f3e041 --- /dev/null +++ b/keyext.api/src/main/python/keyapi/rpc.py @@ -0,0 +1,76 @@ +import abc +import json +from abc import abstractmethod +from multiprocessing import Process, SimpleQueue, Lock, Value + + +class Client(abc.ABC): + @abstractmethod + def handle(self, response): + pass + + +class JsonRPCHandler: + client: Client + + def __init__(self, in_stream, out_stream): + self.input = in_stream + self.out = out_stream + self.__id = 0 + self.client: Client + + self._events = dict() + self._responses = dict() + + # t: Process = Process(target=self.__read) + # t.start() + + def read_message(self): + length = 0 + for clength in self.input.readlines(): + if clength.startswith("Content-Length:"): + length = int(clength[14:]) + break + + payload = self.input.read(2 + length) + r = json.loads(payload) + if "id" in r: # JSON response for request + rid = r["id"] + # self._responses[rid] = r + # if rid in self._events: + # self._events[rid].set() + else: # JSON notification + self.client.handle(r) + return r + + def __read(self): + while True: + self.read_message() + + # def __create_event(self, number): + # self._events[number] = Event() + + def _send(self, method, params): + self.__id += 1 + id = self.__id + # self.__create_event(self.__id) + req = {"jsonrpc": "2.0", "method": method, "params": params, "id": self.__id} + + self._write(json.dumps(req)) + # self._wait_for(self.__id) + + r = dict() + while "id" in r and str(r[id]) != str(id): + r = self.read_message() + return r + + def _write(self, msg): + length = len(msg) + self.out.write(f"Content-Length: {length}\r\n") + self.out.write("\r\n") + self.out.write(msg) + self.out.write("\r\n") + self.out.flush() + + # def _wait_for(self, rid): + # self._events[rid].wait() diff --git a/keyext.api/src/main/python/main.py b/keyext.api/src/main/python/main.py new file mode 100644 index 00000000000..a5cb45321d8 --- /dev/null +++ b/keyext.api/src/main/python/main.py @@ -0,0 +1,13 @@ +import socket +from keyapi import KeyStub, KeyClient + +if __name__ == "__main__": + target = ("localhost", 5151) + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect(target) + input = s.makefile("r", newline="\r\n") + output = s.makefile("w", newline="\r\n") + stub = KeyStub(input, output) + stub.client = KeyClient() + print(stub.list_examples()) From fd5cb79e5953d17b8b6fa900e03652d9cc36428e Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 15 Oct 2023 17:27:16 +0200 Subject: [PATCH 13/50] Creating an JSON-RPC API --- .../java/de/uka/ilkd/key/Identifiable.java | 11 + .../main/java/de/uka/ilkd/key/api/KeYApi.java | 102 --------- .../java/de/uka/ilkd/key/api/Matcher.java | 210 ------------------ .../de/uka/ilkd/key/api/ProjectedNode.java | 65 ------ .../java/de/uka/ilkd/key/api/ProofApi.java | 90 -------- .../uka/ilkd/key/api/ProofManagementApi.java | 129 ----------- .../ilkd/key/api/ProofScriptCommandCall.java | 20 -- .../java/de/uka/ilkd/key/api/ScriptApi.java | 132 ----------- .../de/uka/ilkd/key/api/ScriptResult.java | 114 ---------- .../de/uka/ilkd/key/api/ScriptResults.java | 178 --------------- .../java/de/uka/ilkd/key/api/SearchNode.java | 55 ----- .../uka/ilkd/key/api/VariableAssignments.java | 154 ------------- .../de/uka/ilkd/key/api/package-info.java | 9 - .../uka/ilkd/key/control/KeYEnvironment.java | 162 +++++++++----- .../ProofMacroFacade.java} | 15 +- .../scripts/ProofScriptCommandFacade.java} | 16 +- .../main/java/de/uka/ilkd/key/proof/Goal.java | 47 +++- .../java/de/uka/ilkd/key/proof/Proof.java | 12 +- .../speclang/njml/ContractLoadingTests.java | 65 ++---- .../de/uka/ilkd/key/gui/ExampleChooser.java | 2 +- keyext.api.doc/build.gradle | 4 + .../src/main/java/ExtractMetaData.java | 162 ++++++++++++++ keyext.api/build.gradle | 3 + .../keyproject/key/api/FileTypeAdapter.java | 20 -- .../org/keyproject/key/api/KeyApiImpl.java | 168 ++++++++++++++ .../org/keyproject/key/api/StartServer.java | 56 +---- .../key/api/adapters/KeyAdapter.java | 96 ++++++++ .../key/api/adapters/package-info.java | 7 + .../keyproject/key/api/data/ContractDesc.java | 8 + .../keyproject/key/api/data/FunctionDesc.java | 10 + .../org/keyproject/key/api/data/GoalText.java | 10 + .../keyproject/key/api/data/LoadParams.java | 14 ++ .../{remoteapi => data}/MacroDescription.java | 8 +- .../key/api/data/MacroStatistic.java | 8 + .../org/keyproject/key/api/data/NodeDesc.java | 8 + .../key/api/data/PredicateDesc.java | 8 + .../org/keyproject/key/api/data/PrintId.java | 8 + .../key/api/data/ProblemDefinition.java | 18 ++ .../keyproject/key/api/data/ProofLoading.java | 42 ++++ .../org/keyproject/key/api/data/SortDesc.java | 8 + .../key/api/data/StreategyOptions.java | 8 + .../keyproject/key/api/data/TermAction.java | 8 + .../keyproject/key/api/data/TermActionId.java | 8 + .../api/{remoteapi => data}/TraceValue.java | 2 +- .../keyproject/key/api/data/TreeNodeDesc.java | 8 + .../keyproject/key/api/data/TreeNodeId.java | 8 + .../keyproject/key/api/remoteapi/EnvApi.java | 31 +++ .../keyproject/key/api/remoteapi/EnvId.java | 8 - .../{KeyExampleApi.java => ExampleApi.java} | 2 +- .../keyproject/key/api/remoteapi/GoalApi.java | 32 +++ .../keyproject/key/api/remoteapi/KeyApi.java | 56 +---- .../key/api/remoteapi/KeyApiImpl.java | 56 ----- .../key/api/remoteapi/LoadParams.java | 8 - .../{KeyMetaApi.java => MetaApi.java} | 11 +- .../key/api/remoteapi/ProofApi.java | 48 ++++ .../keyproject/key/api/remoteapi/ProofId.java | 4 - .../key/api/remoteapi/ProofLoading.java | 19 -- .../key/api/remoteapi/ProofTreeApi.java | 26 +++ .../key/api/remoteapi/ServerManagement.java | 60 +++++ .../key/api/remoteclient/ClientApi.java | 2 +- .../org/keyproject/key/api/SimpleClient.java | 2 +- .../key/api/{Client.java => TestRpc.java} | 45 +++- settings.gradle | 1 + 63 files changed, 1093 insertions(+), 1614 deletions(-) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/Identifiable.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/api/package-info.java rename key.core/src/main/java/de/uka/ilkd/key/{api/ProofMacroApi.java => macros/ProofMacroFacade.java} (83%) rename key.core/src/main/java/de/uka/ilkd/key/{api/ProofScriptCommandApi.java => macros/scripts/ProofScriptCommandFacade.java} (79%) create mode 100644 keyext.api.doc/build.gradle create mode 100644 keyext.api.doc/src/main/java/ExtractMetaData.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java rename keyext.api/src/main/java/org/keyproject/key/api/{remoteapi => data}/MacroDescription.java (72%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java rename keyext.api/src/main/java/org/keyproject/key/api/{remoteapi => data}/TraceValue.java (54%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java rename keyext.api/src/main/java/org/keyproject/key/api/remoteapi/{KeyExampleApi.java => ExampleApi.java} (91%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java rename keyext.api/src/main/java/org/keyproject/key/api/remoteapi/{KeyMetaApi.java => MetaApi.java} (64%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java rename keyext.api/src/test/java/org/keyproject/key/api/{Client.java => TestRpc.java} (57%) diff --git a/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java b/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java new file mode 100644 index 00000000000..3be1d2528d8 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java @@ -0,0 +1,11 @@ +package de.uka.ilkd.key; + +/** + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +public interface Identifiable { + default String identification() { + return getClass().getName() + "_" + hashCode(); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java deleted file mode 100644 index dc89908c39c..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/KeYApi.java +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.io.File; -import java.util.List; - -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.io.ProblemLoaderException; -import de.uka.ilkd.key.util.KeYConstants; - -/** - * The Entry Point. - *

    - * This facility is the entry point to the different KeY apis. Currently it support the - * bootstrapping of the {@link KeYEnvironment} and the loading of proofs. - *

    - * Created at 6.4.17 - * - * @author Sarah Grebing - * @author Alexander Weigl - * @see ProofScriptCommandApi - */ -public abstract class KeYApi { - private static final ProofMacroApi proofMacroApi = new ProofMacroApi(); - private static final ProofScriptCommandApi scriptCommandApi = new ProofScriptCommandApi(); - - /** - * Create a new KeY API and create the sub APIs - */ - private KeYApi() { - } - - /** - * - * @return - */ - public static String getVersion() { - return KeYConstants.INTERNAL_VERSION; - } - - - /** - * @return non-null - */ - public static ProofScriptCommandApi getScriptCommandApi() { - return scriptCommandApi; - } - - /** - * @return a non-null references to the macro api - */ - public static ProofMacroApi getMacroApi() { - return proofMacroApi; - } - - /** - * @param keyFile - * @return - * @throws ProblemLoaderException - */ - public static ProofManagementApi loadFromKeyFile(File keyFile) throws ProblemLoaderException { - return new ProofManagementApi(KeYEnvironment.load(keyFile)); - } - - /** - * @param location - * @param classPath - * @param bootClassPath - * @param includes - * @return - * @throws ProblemLoaderException - */ - public static ProofManagementApi loadProof(File location, List classPath, - File bootClassPath, List includes) throws ProblemLoaderException { - return new ProofManagementApi( - KeYEnvironment.load(location, classPath, bootClassPath, includes)); - } - - /** - * @param javaSourceCode - * @return - * @throws ProblemLoaderException - */ - public static ProofManagementApi loadProof(File javaSourceCode) throws ProblemLoaderException { - return loadProof(javaSourceCode, null, null, null); - } - - /** - * Load a proof file, creates a KeY environment that can be accessed with other methods from - * this facade - * - * @param file Path to the source code folder/file or to a *.proof file - * @param classPaths Optionally: Additional specifications for API classes - * @param bootClassPath Optionally: Different default specifications for Java API - * @param includes Optionally: Additional includes to consider - */ - public abstract void loadProofFile(File file, List classPaths, File bootClassPath, - List includes); - -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java b/key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java deleted file mode 100644 index 2c628c45ff2..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/Matcher.java +++ /dev/null @@ -1,210 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.*; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.Name; -import de.uka.ilkd.key.logic.Sequent; -import de.uka.ilkd.key.logic.SequentFormula; -import de.uka.ilkd.key.logic.op.SchemaVariable; -import de.uka.ilkd.key.nparser.KeyAst; -import de.uka.ilkd.key.nparser.KeyIO; -import de.uka.ilkd.key.nparser.ParsingFacade; -import de.uka.ilkd.key.rule.*; -import de.uka.ilkd.key.rule.inst.SVInstantiations; -import de.uka.ilkd.key.rule.match.vm.VMTacletMatcher; - -import org.key_project.util.collection.ImmutableArray; -import org.key_project.util.collection.ImmutableList; - -import org.antlr.v4.runtime.CharStreams; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Matcher to deal with matching a string pattern against a sequent - * - * @author S.Grebing - */ -public class Matcher { - private static final Logger LOGGER = LoggerFactory.getLogger(Matcher.class); - private final ProofApi api; - - /** - * Creates a new matcher for the given proof and environment. - * - * @param api reference to proof api in order to get access to the key environment - */ - public Matcher(ProofApi api) { - this.api = api; - } - - /** - * Matches a sequent against a sequent pattern (a schematic sequent) returns a list of Nodes - * containing matching results from where the information about instantiated schema variables - * can be extracted. If no match was possible the list is exmpt. - * - * @param pattern a string representation of the pattern sequent against which the current - * sequent should be matched - * @param currentSeq current concrete sequent - * @param assignments variables appearing in the pattern as schemavariables with their - * corresponding type in KeY - * @return List of VariableAssignments (possibly empty if no match was found) - */ - // List of VarAssignment - public List matchPattern(String pattern, Sequent currentSeq, - VariableAssignments assignments) { - // copy services in order to not accidently set assignments and namespace for environment - Services copyServices = api.getEnv().getServices().copy(false); - // Aufbau der Deklarationen fuer den NameSpace - buildNameSpace(assignments, copyServices); - // Zusammenbau des Pseudotaclets - // Parsen des Taclets - String patternString = "matchPattern{\\assumes(" + pattern + ") \\find (==>) \\add (==>)}"; - - Taclet t = parseTaclet(patternString, copyServices); - - // Build Matcher for Matchpattern - VMTacletMatcher tacletMatcher = new VMTacletMatcher(t); - - // patternSequent should not be null, as we have created it - assert t.ifSequent() != null; - Sequent patternSeq = t.ifSequent(); - int asize = patternSeq.antecedent().size(); - int size = asize + patternSeq.succedent().size(); - // Iterator durch die Pattern-Sequent - - List finalCandidates = new ArrayList<>(100); - if (size > 0) { - // Iteratoren durch die Sequent - ImmutableArray antecCand = - IfFormulaInstSeq.createList(currentSeq, true, copyServices); - ImmutableArray succCand = - IfFormulaInstSeq.createList(currentSeq, false, copyServices); - - SequentFormula[] patternArray = new SequentFormula[patternSeq.size()]; - int i = 0; - for (SequentFormula fm : patternSeq) { - patternArray[i++] = fm; - } - - - Queue queue = new LinkedList<>(); - // init - queue.add(new SearchNode(patternArray, asize)); - - - while (!queue.isEmpty()) { - SearchNode node = queue.remove(); - boolean inAntecedent = node.isAntecedent(); - LOGGER.debug(inAntecedent ? "In Antec: " : "In Succ"); - - IfMatchResult ma = tacletMatcher.matchIf((inAntecedent ? antecCand : succCand), - node.getPatternTerm(), node.getMatchConditions(), copyServices); - - if (!ma.getMatchConditions().isEmpty()) { - ImmutableList testma = ma.getMatchConditions(); - - for (MatchConditions matchConditions : testma) { - SearchNode sn = new SearchNode(node, matchConditions); - if (sn.isFinished()) { - finalCandidates.add(sn); - } else { - queue.add(sn); - } - } - } else { - LOGGER.debug("Pattern Empty"); - } - } - } - List matches = new ArrayList<>(); - if (!finalCandidates.isEmpty()) { - for (SearchNode finalCandidate : finalCandidates) { - VariableAssignments va = extractAssignments(finalCandidate, assignments); - matches.add(va); - } - } - return matches; - } - - /** - * Extract the matching results from each SearchNode and tranform these to Variable Assigments - * - * @param sn SearchNode - * @return VariableAssigments containing the assignments fo matching results to schemavariables - */ - private VariableAssignments extractAssignments(SearchNode sn, VariableAssignments assignments) { - VariableAssignments va = new VariableAssignments(); - SVInstantiations insts = sn.getInstantiations(); - Set varNames = assignments.getTypeMap().keySet(); - for (String varName : varNames) { - SchemaVariable sv = insts.lookupVar(new Name(varName)); - Object value = insts.getInstantiation(sv); - va.addAssignmentWithType(varName, value, assignments.getTypeMap().get(varName)); - } - return va; - - } - - /** - * Adds the variables of VariableAssignments to the namespace - * - * @param assignments VariabelAssignments containing variable names and types - */ - private void buildNameSpace(VariableAssignments assignments, Services services) { - String decalarations = buildDecls(assignments); - parseDecls(decalarations, services); - - } - - /** - * Builds a string that is used to create a new schemavariable declaration for the matchpattern - * - * @param assignments varaiables appearing as schema varaibels in the match pattern and their - * types (in KeY) - * @return a String representing the declaration part of a taclet for teh matchpattern - */ - private String buildDecls(VariableAssignments assignments) { - Map typeMap = assignments.getTypeMap(); - String schemaVars = "\\schemaVariables {\n"; - final List strn = new ArrayList<>(); - - typeMap.forEach((id, type) -> strn.add(toDecl(id, type))); - schemaVars += String.join("\n", strn); - schemaVars += "}"; - LOGGER.debug("Schema Variables: {}", schemaVars); - return schemaVars; - } - - private String toDecl(String id, VariableAssignments.VarType type) { - return type.getKeYDeclarationPrefix() + " " + id + ";"; - } - - /** - * Parse the declaration string for the current pattern and add the variables to the namespace - * - * @param s declaration part of a taclet - */ - public void parseDecls(String s, Services services) { - try { - KeyIO io = new KeyIO(services); - KeyAst.File ctx = ParsingFacade.parseFile(CharStreams.fromString(s)); - io.evalDeclarations(ctx); - } catch (Exception e) { - LOGGER.error("Exception while Parsing.", e); - } - } - - private Taclet parseTaclet(String s, Services services) { - KeyIO io = new KeyIO(services); - KeyAst.File ctx = ParsingFacade.parseFile(CharStreams.fromString(s)); - io.evalDeclarations(ctx); - io.evalFuncAndPred(ctx); - return io.findTaclets(ctx).get(0); - } - -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java deleted file mode 100644 index d255acb757a..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProjectedNode.java +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import de.uka.ilkd.key.logic.Sequent; -import de.uka.ilkd.key.proof.Node; -import de.uka.ilkd.key.proof.NodeInfo; - -/** - * Wrapper for a proof node with utilities methods to - * - * @author Sarah Grebing - * @author Alexander Weigl - */ -public class ProjectedNode { - - private final Node proofNode; - - private final ProjectedNode parent; - - /** - * Creates the wrapper object for a proof node - * - * @param node - * @param parent - */ - public ProjectedNode(Node node, ProjectedNode parent) { - this.proofNode = node; - this.parent = parent; - } - - /** - * Return the sequent of a proof node - * - * @return de.uka.ilkd.key.logic.Sequent s - */ - public Sequent getSequent() { - return proofNode.sequent(); - } - - public ProjectedNode getParent() { - return this.parent; - } - - public boolean isRoot() { - return getParent() == null; - } - - public NodeInfo getNodeInfo() { - return proofNode.getNodeInfo(); - } - - public boolean isPseudoNode() { - return proofNode == null; - } - - public Node getProofNode() { - return proofNode; - } - - public static ProjectedNode pseudoRoot() { - return new ProjectedNode(null, null); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java deleted file mode 100644 index 9a33c3a93b9..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofApi.java +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.io.IOException; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.stream.Collectors; - -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.mgt.RuleJustification; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.rule.NoPosTacletApp; -import de.uka.ilkd.key.rule.OneStepSimplifier; -import de.uka.ilkd.key.util.MiscTools; - -import org.key_project.util.collection.ImmutableList; - -/** - * @author Alexander Weigl - * @version 1 (21.04.17) - */ -public class ProofApi { - private final KeYEnvironment env; - private final Proof proof; - - public ProofApi(Proof proof, KeYEnvironment currentEnv) { - this.proof = proof; - this.env = currentEnv; - } - - public ScriptApi getScriptApi() { - return new ScriptApi(this); - } - - /** - * Save current Proof-> ProofApi - */ - public void saveProof() throws IOException { - // TODO - } - - public KeYEnvironment getEnv() { - return env; - } - - public Proof getProof() { - return proof; - } - - public List getOpenGoals() { - ImmutableList goals = proof.openGoals(); - return goals.stream().map(g -> new ProjectedNode(g.node(), null)) - .collect(Collectors.toList()); - } - - public ProjectedNode getFirstOpenGoal() { - return getOpenGoals().get(0); - } - - public Set getRules() { - Set s = new TreeSet<>(); - Goal goal = proof.getSubtreeGoals(proof.root()).head(); - - for (final BuiltInRule br : goal.ruleAppIndex().builtInRuleAppIndex().builtInRuleIndex() - .rules()) { - s.add(br.displayName()); - } - - Set set = goal.ruleAppIndex().tacletIndex().allNoPosTacletApps(); - OneStepSimplifier simplifier = MiscTools.findOneStepSimplifier(goal.proof()); - if (simplifier != null && !simplifier.isShutdown()) { - set.addAll(simplifier.getCapturedTaclets()); - } - - for (final NoPosTacletApp app : set) { - RuleJustification just = goal.proof().mgt().getJustification(app); - if (just == null) { - continue; // do not break system because of this - } - s.add(app.taclet().displayName()); - } - - return s; - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java deleted file mode 100644 index 6ef8191acf3..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofManagementApi.java +++ /dev/null @@ -1,129 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.logic.op.IObserverFunction; -import de.uka.ilkd.key.proof.init.ProofInputException; -import de.uka.ilkd.key.proof.init.ProofOblInput; -import de.uka.ilkd.key.speclang.Contract; -import de.uka.ilkd.key.util.KeYTypeUtil; - -import org.key_project.util.collection.ImmutableSet; - -/** - * This class serves as a facade to all functionalities that are needed for proof management, i.e., - * loading proof files, retrieving the proof obligations - * - * @author Sarah Grebing. - */ -public class ProofManagementApi { - private final KeYEnvironment currentEnv; - private final List proofContracts = new ArrayList<>(); - private HashSet ruleNames; - - public ProofManagementApi(KeYEnvironment env) { - currentEnv = env; - } - - public Services getServices() { - return currentEnv.getServices(); - } - - /** - * Retrieve a list of all available contracts - * - * @return {@link List}; can be null if no file was loaded before (we should throw an - * exception here) - */ - public List getProofContracts() { - if (proofContracts.isEmpty()) { - buildContracts(); - } - return proofContracts; - } - - /** - * constructs the possible proof contracts from the java info in the environment. - */ - private void buildContracts() { - proofContracts.clear(); - Set kjts = currentEnv.getJavaInfo().getAllKeYJavaTypes(); - for (KeYJavaType type : kjts) { - if (!KeYTypeUtil.isLibraryClass(type)) { - ImmutableSet targets = - currentEnv.getSpecificationRepository().getContractTargets(type); - for (IObserverFunction target : targets) { - ImmutableSet contracts = - currentEnv.getSpecificationRepository().getContracts(type, target); - for (Contract contract : contracts) { - proofContracts.add(contract); - } - } - } - } - } - - /** - * @param contract - * @return - * @throws ProofInputException - */ - public ProofApi startProof(ProofOblInput contract) throws ProofInputException { - return new ProofApi(currentEnv.createProof(contract), currentEnv); - } - - /** - * @param contract - * @return - * @throws ProofInputException - */ - public ProofApi startProof(Contract contract) throws ProofInputException { - return startProof(contract.createProofObl(currentEnv.getInitConfig(), contract)); - } - - public ProofApi getLoadedProof() { - return new ProofApi(currentEnv.getLoadedProof(), currentEnv); - } - - /** - * Constructs a set containing all names of a taclets that are registered in the current - * environment. - *

    - * The result is cached to speed up further calls.s - * - * @return always returns a non-null hash set. - */ - public Set getRuleNames() { - if (ruleNames == null) { - ruleNames = new HashSet<>(); - currentEnv.getInitConfig().activatedTaclets() - .forEach(taclet -> ruleNames.add(taclet.displayName())); - - currentEnv.getInitConfig().builtInRules().forEach(t -> ruleNames.add(t.displayName())); - } - return ruleNames; - } - - /* - * public KeYApi.CommandType getCommandType(String identifier) { if - * (KeYApi.getMacroApi().getMacro(identifier) != null) { return KeYApi.CommandType.MACRO; } - * - * if (KeYApi.getScriptCommandApi().getScriptCommands(identifier) != null) { return - * KeYApi.CommandType.SCRIPT; } - * - * if (getRuleNames().contains(identifier)) { return KeYApi.CommandType.RULE; } - * - * return KeYApi.CommandType.UNKNOWN; } - * - * enum CommandType { SCRIPT, RULE, MACRO, UNKNOWN; } - */ -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java b/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java deleted file mode 100644 index 42c2e08f405..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandCall.java +++ /dev/null @@ -1,20 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; - -/** - * @param - * @author Alexander Weigl - */ -public class ProofScriptCommandCall { - final T parameter; - final ProofScriptCommand command; - - public ProofScriptCommandCall(ProofScriptCommand command, T arguments) { - parameter = arguments; - this.command = command; - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java b/key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java deleted file mode 100644 index 7e5a8c5841b..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptApi.java +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; - -import de.uka.ilkd.key.control.AbstractUserInterfaceControl; -import de.uka.ilkd.key.logic.Sequent; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.macros.scripts.EngineState; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; -import de.uka.ilkd.key.macros.scripts.ScriptException; -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.Node; - -import org.key_project.util.collection.ImmutableList; - -/** - * This API class offers methods to apply script commands and match commands - * - * @author Alexander Weigl - * @author S. Grebing - */ -public class ScriptApi { - private final ProofApi api; - private final EngineState state; - private final Matcher matcher; - - public ScriptApi(ProofApi proofApi) { - api = proofApi; - state = new EngineState(api.getProof()); - matcher = new Matcher(api); - } - - /** - * Matches a sequent against a sequent pattern (a schematic sequent) returns a list of Nodes - * containing matching results from where the information about instantiated schema variables - * can be extracted. If no match was possible the list is exmpt. - * - * @param pattern a string representation of the pattern sequent against which the current - * sequent should be matched - * @param currentSeq current concrete sequent - * @param assignments variables appearing in the pattern as schemavariables with their - * corresponding type in KeY - * @return List of VariableAssignments (possibly empty if no match was found) - */ - public List matchPattern(String pattern, Sequent currentSeq, - VariableAssignments assignments) { - return matcher.matchPattern(pattern, currentSeq, assignments); - } - - /** - * Execute ScriptCommand onto goal node - * - * @param call to be applied with parameters set - * @param onNode the starting node - * @return List of new proof goals (possibly empty) Should throw an Exception if command not - * applicable? - */ - public ScriptResults executeScriptCommand(ProofScriptCommandCall call, - ProjectedNode onNode) throws ScriptException, InterruptedException { - // TODO VariableAssignments should be in instantiateCommand - - state.setGoal(onNode.getProofNode()); - call.command.execute((AbstractUserInterfaceControl) api.getEnv().getUi(), call.parameter, - state); - - ImmutableList goals = api.getProof().getSubtreeGoals(onNode.getProofNode()); - // TODO filter for open goals if necessary - ScriptResults sr = new ScriptResults(); - - goals.forEach(g -> sr.add(ScriptResult.create(g.node(), onNode, call))); - - return sr; - } - - /** - * Evaluate the arguments passed to a command - * - * @param arguments - * @param - * @return - */ - public ProofScriptCommandCall instantiateCommand(ProofScriptCommand command, - Map arguments) throws Exception { - return new ProofScriptCommandCall<>(command, command.evaluateArguments(state, arguments)); - } - - - /** - * - * @param term - * @param assignments - * @return - * @throws Exception either for Syntax or Type error - */ - public Term toTerm(String term, VariableAssignments assignments) throws Exception { - // TODO - return null; - } - - /** - * ~> Beweisbaum -> Shallow Copy hier implementieren - * - * @param root - * @param end - * @return - */ - public ProjectedNode getIntermediateTree(ScriptResults root, ScriptResults end) { - /* - * Baum suche, startet bei allen Nodes von root. - * - * Endet sobald ein Node von end erreicht ist. - */ - ProjectedNode pseudoRoot = ProjectedNode.pseudoRoot(); - Queue queue = new LinkedList<>(); - root.forEach(r -> queue.add(r.getProjectedNode().getProofNode())); - - while (!queue.isEmpty()) { - - } - - - return pseudoRoot; - } - - -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java b/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java deleted file mode 100644 index b5213cb0133..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResult.java +++ /dev/null @@ -1,114 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.List; -import java.util.Set; - -import de.uka.ilkd.key.java.PositionInfo; -import de.uka.ilkd.key.proof.Node; - -/** - * Object that represents one result goal of a script command It holds a reference to its parent - * node and to the list of variables and their values for this result Created by S. Grebing - */ -public class ScriptResult { - - /** - * The current goal node - */ - private ProjectedNode newNode; - - /** - * the parent scriptNode to which the scriptcommand was applied - */ - private ProjectedNode parentNode; - - /** - * The scriptcommand that lead to this result - */ - private ProofScriptCommandCall call; - - /** - * The reference to the variableassingments for this result - */ - // private VariableAssignments assignments; - - /** - * The list of labels for the result - */ - private Set> labels; - - /** - * List with line numbers - */ - private List linenumbers; - - // getLineNumbers hier - - /** - * - */ - ScriptResult() { - // nulls - } - - public static ScriptResult create(Node node, ProjectedNode onNode, - ProofScriptCommandCall call) { - ScriptResult sr = new ScriptResult(); - sr.parentNode = onNode; - sr.newNode = new ProjectedNode(node, onNode); - sr.call = call; - return sr; - } - - public ProjectedNode getNewNode() { - return newNode; - } - - public ScriptResult setNewNode(ProjectedNode newNode) { - this.newNode = newNode; - return this; - } - - public ProjectedNode getParentNode() { - return parentNode; - } - - public ScriptResult setParentNode(ProjectedNode parentNode) { - this.parentNode = parentNode; - return this; - } - - public ProofScriptCommandCall getCall() { - return call; - } - - public ScriptResult setCall(ProofScriptCommandCall call) { - this.call = call; - return this; - } - - public Set> getLabels() { - return labels; - } - - public ScriptResult setLabels(Set> labels) { - this.labels = labels; - return this; - } - - public List getLinenumbers() { - return linenumbers; - } - - public ScriptResult setLinenumbers(List linenumbers) { - this.linenumbers = linenumbers; - return this; - } - - public ProjectedNode getProjectedNode() { - return getNewNode(); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java b/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java deleted file mode 100644 index efc2bb66b2f..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ScriptResults.java +++ /dev/null @@ -1,178 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Stream; - -/** - * @author Alexander Weigl - * @version 1 (21.04.17) - */ -public class ScriptResults implements List { - private final List delegated = new ArrayList<>(); - - @Override - public int size() { - return delegated.size(); - } - - @Override - public boolean isEmpty() { - return delegated.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegated.contains(o); - } - - @Override - public Iterator iterator() { - return delegated.iterator(); - } - - @Override - public Object[] toArray() { - return delegated.toArray(); - } - - @Override - public T[] toArray(T[] a) { - return delegated.toArray(a); - } - - @Override - public boolean add(ScriptResult scriptResult) { - return delegated.add(scriptResult); - } - - @Override - public boolean remove(Object o) { - return delegated.remove(o); - } - - @Override - public boolean containsAll(Collection c) { - return delegated.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - return delegated.addAll(c); - } - - @Override - public boolean addAll(int index, Collection c) { - return delegated.addAll(index, c); - } - - @Override - public boolean removeAll(Collection c) { - return delegated.removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return delegated.retainAll(c); - } - - @Override - public void replaceAll(UnaryOperator operator) { - delegated.replaceAll(operator); - } - - @Override - public void sort(Comparator c) { - delegated.sort(c); - } - - @Override - public void clear() { - delegated.clear(); - } - - @Override - public boolean equals(Object o) { - return delegated.equals(o); - } - - @Override - public int hashCode() { - return delegated.hashCode(); - } - - @Override - public ScriptResult get(int index) { - return delegated.get(index); - } - - @Override - public ScriptResult set(int index, ScriptResult element) { - return delegated.set(index, element); - } - - @Override - public void add(int index, ScriptResult element) { - delegated.add(index, element); - } - - @Override - public ScriptResult remove(int index) { - return delegated.remove(index); - } - - @Override - public int indexOf(Object o) { - return delegated.indexOf(o); - } - - @Override - public int lastIndexOf(Object o) { - return delegated.lastIndexOf(o); - } - - @Override - public ListIterator listIterator() { - return delegated.listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - return delegated.listIterator(index); - } - - @Override - public List subList(int fromIndex, int toIndex) { - return delegated.subList(fromIndex, toIndex); - } - - @Override - public Spliterator spliterator() { - return delegated.spliterator(); - } - - @Override - public boolean removeIf(Predicate filter) { - return delegated.removeIf(filter); - } - - @Override - public Stream stream() { - return delegated.stream(); - } - - @Override - public Stream parallelStream() { - return delegated.parallelStream(); - } - - @Override - public void forEach(Consumer action) { - delegated.forEach(action); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java b/key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java deleted file mode 100644 index bf08e9862ac..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/SearchNode.java +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import de.uka.ilkd.key.logic.SequentFormula; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.rule.MatchConditions; -import de.uka.ilkd.key.rule.inst.SVInstantiations; - -/** - * Created by sarah on 5/2/17. - */ -public final class SearchNode { - private final SequentFormula[] pattern; - private final int pos; - private final int succAntPos; - private final MatchConditions mc; - - - public SearchNode(SequentFormula[] pattern, int succAntPos) { - this.pattern = pattern; - this.pos = 0; - this.succAntPos = succAntPos; - this.mc = MatchConditions.EMPTY_MATCHCONDITIONS; - } - - public SearchNode(SearchNode parent, MatchConditions cond) { - this.pattern = parent.pattern; - this.succAntPos = parent.succAntPos; - int parentPos = parent.pos; - this.pos = parentPos + 1; - mc = cond; - } - - public boolean isAntecedent() { - return pos < succAntPos; - } - - public Term getPatternTerm() { - return pattern[pos].formula(); - } - - public boolean isFinished() { - return pos >= pattern.length; - } - - public SVInstantiations getInstantiations() { - return mc == null ? null : mc.getInstantiations(); - } - - public MatchConditions getMatchConditions() { - return mc; - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java b/key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java deleted file mode 100644 index 6f2fee63133..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/VariableAssignments.java +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; - -import java.util.HashMap; -import java.util.Map; - -/** - * Class to represent current Variable assigments. Created by S.Grebing - */ -public class VariableAssignments { - - - public enum VarType { - INT("\\term int"), BOOL("\\term bool"), ANY("\\term any"), INT_ARRAY("\\term int[]"), - OBJECT("\\term Object"), HEAP("\\term Heap"), FIELD("\\term Field"), - LOCSET("\\term LocSet"), FORMULA("\\formula"), SEQ("\\term Seq"); - - private final String declPrefix; - - VarType(String declPrefix) { - this.declPrefix = declPrefix; - } - - public String getKeYDeclarationPrefix() { - return declPrefix; - } - } - - /** - * Reference to parent assignments - */ - private final VariableAssignments parent; - - /** - * Current Assignments - */ - private final Map currentAssignments; - - /** - * Type Map of assignments - */ - private final Map typeMap; - - /** - * Create new, empty variable assignment, to add variables - * - * @param parentAssignments the parent assignments - */ - public VariableAssignments(VariableAssignments parentAssignments) { - this.currentAssignments = new HashMap<>(); - this.typeMap = new HashMap<>(); - this.parent = parentAssignments; - } - - - /** - * Default constructor - */ - public VariableAssignments() { - this.currentAssignments = new HashMap<>(); - this.typeMap = new HashMap<>(); - this.parent = null; - } - - - /** - * Get the value of a stored variable name TODO Exception spezifischer - * - * @param varName - * @return Value of variable - */ - public Object getVarValue(String varName) throws Exception { - if (currentAssignments.containsKey(varName)) { - return currentAssignments.get(varName); - } else { - if (parent != null) { - return parent.getVarValue(varName); - } else { - throw new Exception("Variable " + varName + " could not be found"); - } - } - } - - /** - * Add a variable assignment with type and value - * - * @param varName - * @param value - * @param type - */ - public void addAssignmentWithType(String varName, Object value, VarType type) { - typeMap.put(varName, type); - currentAssignments.put(varName, value); - - } - - /** - * Add a variable assignment without type - * - * @param varName - * @param value - */ - public void addAssignment(String varName, Object value) throws Exception { - if (typeMap.containsKey(varName)) { - currentAssignments.put(varName, value); - } else { - throw new Exception("Variable " + varName + "must be declared first"); - } - - } - - /** - * TODO better exception Add a new type declaration - * - * @param varName - * @param type - */ - public void addType(String varName, VarType type) throws Exception { - if (typeMap.containsKey(varName)) { - if (typeMap.get(varName) != type) { - throw new Exception("Variable " + varName + "was already declared with type " - + typeMap.get(varName).toString()); - } - } else { - typeMap.put(varName, type); - } - } - - /** - * Returns the map of ID -> Type mappings - * - * @return - */ - public Map getTypeMap() { - return this.typeMap; - } - - - /* - * public Object getValue(String name) { return null; } - * - * public Type getType() { return null; } - * - * public void setType(Type type) { - * - * } - * - * public void setValue(String name) { - * - * } - */ -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/package-info.java b/key.core/src/main/java/de/uka/ilkd/key/api/package-info.java deleted file mode 100644 index 402b65aa83c..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/api/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This package gives an high-level entry point to the KeY world. - * - * @author Alexander Weigl - * @author Sarah Grebing - * @version 1 (21.04.17) - * @see de.uka.ilkd.key.api.KeYApi - */ -package de.uka.ilkd.key.api; diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java index 370527fb280..dc2936d64e7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java @@ -3,13 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.control; -import java.io.File; -import java.util.List; -import java.util.Properties; -import java.util.function.Consumer; - import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.op.IObserverFunction; import de.uka.ilkd.key.parser.Location; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.init.InitConfig; @@ -20,7 +17,15 @@ import de.uka.ilkd.key.proof.io.AbstractProblemLoader.ReplayResult; import de.uka.ilkd.key.proof.io.ProblemLoaderException; import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.rule.Rule; +import de.uka.ilkd.key.speclang.Contract; +import de.uka.ilkd.key.util.KeYTypeUtil; import de.uka.ilkd.key.util.Pair; +import org.key_project.util.collection.ImmutableSet; + +import java.io.File; +import java.util.*; +import java.util.function.Consumer; /** * Instances of this class are used to collect and access all relevant information for verification @@ -62,7 +67,7 @@ public class KeYEnvironment { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig) { @@ -72,11 +77,11 @@ public KeYEnvironment(U ui, InitConfig initConfig) { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig, Proof loadedProof, - Pair proofScript, ReplayResult replayResult) { + Pair proofScript, ReplayResult replayResult) { this.ui = ui; this.initConfig = initConfig; this.loadedProof = loadedProof; @@ -175,15 +180,15 @@ public Proof createProof(ProofOblInput input) throws ProofInputException { * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. + * @param location The location to load. + * @param classPaths The class path entries to use. * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param includes Optional includes to consider. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes) + List classPaths, File bootClassPath, List includes) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, false); } @@ -192,103 +197,103 @@ public static KeYEnvironment load(File location, * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes, - RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, null, - ruleCompletionHandler, false); + ruleCompletionHandler, false); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as - * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file - * will be used for new proofs. + * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file + * will be used for new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, null, null, - forceNewProfileOfNewProofs); + forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, poPropertiesToForce, - ruleCompletionHandler, - null, forceNewProfileOfNewProofs); + ruleCompletionHandler, + null, forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. - * @param callbackProofLoaded An optional callback (called when the proof is loaded, before - * replay) + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param callbackProofLoaded An optional callback (called when the proof is loaded, before + * replay) * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - Consumer callbackProofLoaded, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + Consumer callbackProofLoaded, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { DefaultUserInterfaceControl ui = new DefaultUserInterfaceControl(ruleCompletionHandler); AbstractProblemLoader loader = ui.load(profile, location, classPaths, bootClassPath, - includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); + includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); InitConfig initConfig = loader.getInitConfig(); return new KeYEnvironment<>(ui, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); } public static KeYEnvironment load(File keyFile) @@ -319,4 +324,41 @@ public boolean isDisposed() { public Pair getProofScript() { return proofScript; } + + /** + * Retrieve a list of all available contracts for all known Java types. + * + * @return a non-null list, possible empty + */ + public List getAvailableContracts() { + List proofContracts = new ArrayList<>(512); + Set kjts = getJavaInfo().getAllKeYJavaTypes(); + for (KeYJavaType type : kjts) { + if (!KeYTypeUtil.isLibraryClass(type)) { + ImmutableSet targets = getSpecificationRepository().getContractTargets(type); + for (IObserverFunction target : targets) { + ImmutableSet contracts = getSpecificationRepository().getContracts(type, target); + for (Contract contract : contracts) { + proofContracts.add(contract); + } + } + } + } + return proofContracts; + } + + + /** + * Constructs a list containing all known rules that are registered in the current + * environment. + * + * @return always returns a non-null list + */ + public List getRules() { + var rules = new ArrayList(4096); + rules.addAll(getInitConfig().activatedTaclets()); + getInitConfig().builtInRules().forEach(rules::add); + return rules; + } + } diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofMacroApi.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java similarity index 83% rename from key.core/src/main/java/de/uka/ilkd/key/api/ProofMacroApi.java rename to key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java index fbdf19d343d..29b9579f640 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofMacroApi.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java @@ -1,25 +1,30 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; +package de.uka.ilkd.key.macros; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; -import de.uka.ilkd.key.macros.ProofMacro; - /** * This class provides access to the proof script commands. * * @author Alexander Weigl * @version 1 (09.05.17) */ -public class ProofMacroApi { +public class ProofMacroFacade { + private static ProofMacroFacade INSTANCE; + + public static ProofMacroFacade instance() { + if (INSTANCE == null) INSTANCE = new ProofMacroFacade(); + return INSTANCE; + } + private final Map commandMap = new HashMap<>(); - public ProofMacroApi() { + public ProofMacroFacade() { initialize(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandApi.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java similarity index 79% rename from key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandApi.java rename to key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java index bd23b64bc18..44a26161832 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/api/ProofScriptCommandApi.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java @@ -1,28 +1,34 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.api; +package de.uka.ilkd.key.macros.scripts; + +import de.uka.ilkd.key.smt.IllegalNumberException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; - /** * This class provides access to the proof script commands. * * @author Alexander Weigl * @version 1 (21.04.17) */ -public class ProofScriptCommandApi { +public class ProofScriptCommandFacade { + private static ProofScriptCommandFacade INSTANCE; private final Map> commandMap = new HashMap<>(); - public ProofScriptCommandApi() { + public ProofScriptCommandFacade() { initialize(); } + public static ProofScriptCommandFacade instance() { + if(INSTANCE == null) INSTANCE = new ProofScriptCommandFacade(); + return INSTANCE; + } + @SuppressWarnings("rawtypes") private void initialize() { ServiceLoader loader = ServiceLoader.load(ProofScriptCommand.class); diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java index b86a6a47719..6198a8b88d9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java @@ -3,10 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.proof; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicLong; import de.uka.ilkd.key.java.Services; @@ -16,6 +13,7 @@ import de.uka.ilkd.key.logic.op.ProgramVariable; import de.uka.ilkd.key.pp.LogicPrinter; import de.uka.ilkd.key.pp.NotationInfo; +import de.uka.ilkd.key.proof.mgt.RuleJustification; import de.uka.ilkd.key.proof.proofevent.NodeChangeJournal; import de.uka.ilkd.key.proof.proofevent.RuleAppInfo; import de.uka.ilkd.key.proof.rulefilter.TacletFilter; @@ -26,6 +24,7 @@ import de.uka.ilkd.key.strategy.AutomatedRuleApplicationManager; import de.uka.ilkd.key.strategy.QueueRuleApplicationManager; import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.util.MiscTools; import de.uka.ilkd.key.util.properties.MapProperties; import de.uka.ilkd.key.util.properties.Properties; import de.uka.ilkd.key.util.properties.Properties.Property; @@ -716,6 +715,13 @@ public List getAllBuiltInRuleApps() { return ruleApps; } + /** + * Return a list with available taclet application on this goal. + */ + public List getAllTacletApps() { + return getAllTacletApps(proof().getServices()); + } + public List getAllTacletApps(Services services) { RuleAppIndex index = ruleAppIndex(); index.autoModeStopped(); @@ -740,4 +746,37 @@ protected boolean filter(Taclet taclet) { return allApps; } + /** + * Returns a list with all known rule applications within this proof goal. + */ + public List getAllAvailableRules() { + var taclets = getAllTacletApps(); + var builtin = getAllBuiltInRuleApps(); + builtin.addAll(taclets); + return builtin; + } + + public List getAvailableRules() { + var s = new ArrayList(2048); + for (final BuiltInRule br : ruleAppIndex().builtInRuleAppIndex() + .builtInRuleIndex().rules()) { + s.add(br); + } + + Set set = ruleAppIndex().tacletIndex().allNoPosTacletApps(); + OneStepSimplifier simplifier = MiscTools.findOneStepSimplifier(proof()); + if (simplifier != null && !simplifier.isShutdown()) { + set.addAll(simplifier.getCapturedTaclets()); + } + + for (final NoPosTacletApp app : set) { + RuleJustification just = proof().mgt().getJustification(app); + if (just == null) { + continue; // do not break system because of this + } + s.add(app.taclet()); //TODO not good + } + return s; + } + } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java index 6b97d88d82d..d7ac6c484d0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java @@ -11,6 +11,7 @@ import java.util.function.Predicate; import javax.swing.*; +import de.uka.ilkd.key.Identifiable; import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.*; @@ -27,6 +28,7 @@ import de.uka.ilkd.key.proof.replay.CopyingProofReplayer; import de.uka.ilkd.key.rule.NoPosTacletApp; import de.uka.ilkd.key.rule.OneStepSimplifier; +import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.merge.MergePartner; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.rule.merge.MergeRuleBuiltInRuleApp; @@ -54,7 +56,7 @@ * information, and methods to apply rules. Furthermore, it offers services that deliver the open * goals, namespaces and several other information about the current state of the proof. */ -public class Proof implements Named { +public class Proof implements Named, Identifiable { /** * The time when the {@link Proof} instance was created. @@ -1475,4 +1477,12 @@ public void copyCachedGoals(Proof referencedFrom, Consumer callbackTota } } } + + /** + * {@inheritDoc} + */ + @Override + public String identification() { + return getClass().getName() + "_" + name + "_" + hashCode(); + } } diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java index 3561874cf37..21f2fbc3674 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java @@ -3,47 +3,32 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.speclang.njml; -import java.io.File; - -import de.uka.ilkd.key.api.KeYApi; -import de.uka.ilkd.key.api.ProofManagementApi; -import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.control.KeYEnvironment; 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.util.HelperClassForTests; - import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.File; +import java.util.stream.Stream; public class ContractLoadingTests { public static final File EXAMPLES_DIR = new File("../key.ui/examples/"); - @Test - public void sumAndMax() throws ProblemLoaderException { - final File javaFile = - new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Services services = file.getServices(); - Logger LOGGER = LoggerFactory.getLogger(ContractLoadingTests.class); - for (Contract proofContract : file.getProofContracts()) { - LOGGER.info(proofContract.getPlainText(services)); - } + static Stream files() { + return Stream.of( + new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java") + ).map(Arguments::of); } - @Test - public void issues1658() throws ProblemLoaderException { - final File javaFile = - new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"); - Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); - } - - @Test + @ParameterizedTest + @MethodSource("files") void issues1717() throws ProblemLoaderException, ProofInputException { File javaFile = new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1717/UnderscoreZero.java"); @@ -55,20 +40,8 @@ void issues1717() throws ProblemLoaderException, ProofInputException { } @Test - public void specMathJavaMathTest() throws ProblemLoaderException { - final File javaFile = - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"); - Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); - } - - @Test - public void specMathBigintMathTest() throws ProblemLoaderException { - final File javaFile = - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java"); - Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); + public void nonEmptyContract(File javaFile) throws ProblemLoaderException { + KeYEnvironment env = KeYEnvironment.load(javaFile); + Assertions.assertFalse(env.getAvailableContracts().isEmpty()); } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java index e37603b344e..16420583f3a 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ExampleChooser.java @@ -301,7 +301,7 @@ public static List listExamples(File examplesDir) { new BufferedReader(new FileReader(index, StandardCharsets.UTF_8))) { while ((line = br.readLine()) != null) { line = line.trim(); - if (line.startsWith("#") || line.length() == 0) { + if (line.startsWith("#") || line.isEmpty()) { continue; } File f = new File(examplesDir, line); diff --git a/keyext.api.doc/build.gradle b/keyext.api.doc/build.gradle new file mode 100644 index 00000000000..f7aadd6467c --- /dev/null +++ b/keyext.api.doc/build.gradle @@ -0,0 +1,4 @@ +dependencies { + implementation("com.github.javaparser:javaparser-core:3.25.5") + implementation("com.github.javaparser:javaparser-symbol-solver-core:3.25.5") +} \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java new file mode 100644 index 00000000000..a9df59adef8 --- /dev/null +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -0,0 +1,162 @@ +import com.github.javaparser.ParseResult; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.TypeDeclaration; +import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; +import com.github.javaparser.javadoc.JavadocBlockTag; +import com.github.javaparser.resolution.SymbolResolver; +import com.github.javaparser.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.TypeSolverBuilder; +import com.github.javaparser.utils.SourceRoot; + +import javax.annotation.Nonnull; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +public class ExtractMetaData { + private static PrintWriter out; + + public static void main(String[] args) throws IOException { + System.out.println("XXX" + Arrays.toString(args)); + ParserConfiguration config = new ParserConfiguration(); + config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); + /*config.setAttributeComments(true); + config.setLexicalPreservationEnabled(false); + config.setStoreTokens(false); + config.setIgnoreAnnotationsWhenAttributingComments(true); + config.setDoNotAssignCommentsPrecedingEmptyLines(true);*/ + //var root = Paths.get(args[0]); + TypeSolver typeSolver = new TypeSolverBuilder() + .withSourceCode("keyext.api/src/main/java") + .withSourceCode("key.core/src/main/java") + .withSourceCode("key.util/src/main/java") + .withCurrentJRE() + .build(); + SymbolResolver symbolResolver = new JavaSymbolSolver(typeSolver); + config.setSymbolResolver(symbolResolver); + var source = new SourceRoot(Paths.get("keyext.api", "src", "main", "java"), config); + var cu = source.tryToParse(); + var jsonSegment = Comparator.comparing(ExtractMetaData::getJsonSegment); + var segments = cu.stream().filter(ParseResult::isSuccessful) + .filter(it -> it.getResult().get().getPrimaryType().isPresent()) + .map(it -> it.getResult().get().getPrimaryType().get()) + .filter(ExtractMetaData::hasJsonSegment) + .sorted(jsonSegment) + .toList(); + + try (var out = new PrintWriter(new FileWriter("doc.md"))) { + ExtractMetaData.out = out; + printHeader(segments); + segments.forEach(ExtractMetaData::printDocumentation); + printFooter(segments); + } + + // "org.keyproject.key.api.remoteapi.KeyApi"; + } + + private static void printDocumentation(TypeDeclaration typeDeclaration) { + out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); + out.println(getJavaDoc(typeDeclaration)); + out.println("\n"); + + for (MethodDeclaration method : typeDeclaration.getMethods()) { + if (!isExported(method)) continue; + + String callName = getCallName(method, typeDeclaration); + + out.format("### %s (type: %s) %n%n", callName, type(method)); + + out.println(getJavaDoc(method)); + + out.println(); + } + } + + private static String getCallName(MethodDeclaration m, TypeDeclaration td) { + var annotationExpr = m.getAnnotationByName("JsonNotification").or( + () -> m.getAnnotationByName("JsonRequest")) + .orElseThrow(); + + var segment = getJsonSegment(td) + "/"; + String name = ""; + + if (annotationExpr.isMarkerAnnotationExpr()) { + name = m.getNameAsString(); + } else if (annotationExpr.isSingleMemberAnnotationExpr()) { + var sma = annotationExpr.asSingleMemberAnnotationExpr(); + name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); + } else { + var ne = annotationExpr.asNormalAnnotationExpr(); + for (MemberValuePair pair : ne.getPairs()) { + switch (pair.getName().asString()) { + case "value": + name = pair.getValue().asLiteralStringValueExpr().getValue(); + break; + case "useSegment": + if (!pair.getValue().asBooleanLiteralExpr().getValue()) { + segment = ""; + } + } + } + } + return segment + name; + } + + + @Nonnull + private static String getJavaDoc(NodeWithJavadoc typeDeclaration) { + if (typeDeclaration.getJavadoc().isPresent()) { + final var javadoc = typeDeclaration.getJavadoc().get(); + return javadoc.getDescription().toText() + + "\n\n" + + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) + .collect(Collectors.joining("\n")); + } + return ""; + } + + private static String type(MethodDeclaration method) { + if (method.getAnnotationByName("JsonNotification").isPresent()) + return "notification"; + if (method.getAnnotationByName("JsonRequest").isPresent()) + return "request"; + return ""; + } + + private static boolean isExported(MethodDeclaration method) { + return method.getAnnotationByName("JsonNotification").isPresent() + || method.getAnnotationByName("JsonRequest").isPresent(); + } + + private static void printHeader(List> segments) { + out.format("# KeY-API%n%n"); + } + + private static void printFooter(List> segments) { + + + } + + + private static boolean hasJsonSegment(TypeDeclaration it) { + return it.getAnnotationByName("JsonSegment").isPresent(); + } + + private static String getJsonSegment(TypeDeclaration it) { + var ae = it.getAnnotationByName("JsonSegment").get(); + return ae.asSingleMemberAnnotationExpr().getMemberValue() + .asLiteralStringValueExpr().getValue(); + } +} diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index 0f3b2743c24..c2b84249430 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -18,6 +18,9 @@ dependencies { implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") implementation("org.eclipse.jetty.websocket:websocket-javax-server:10.0.16") implementation("info.picocli:picocli:4.7.5") + + implementation("com.google.guava:guava:32.1.3-jre") + //for GraalVM annotationProcessor 'info.picocli:picocli-codegen:4.7.5' } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java deleted file mode 100644 index 9c03fdfae41..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/FileTypeAdapter.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.keyproject.key.api; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - -import java.io.File; -import java.io.IOException; - -public class FileTypeAdapter extends TypeAdapter { - @Override - public void write(JsonWriter out, File value) throws IOException { - out.value(value.toString()); - } - - @Override - public File read(JsonReader in) throws IOException { - return new File(in.nextString()); - } -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java new file mode 100644 index 00000000000..248210a9f7f --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -0,0 +1,168 @@ +package org.keyproject.key.api; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.gui.Example; +import de.uka.ilkd.key.gui.ExampleChooser; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.macros.ProofMacro; +import de.uka.ilkd.key.macros.ProofMacroFacade; +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import de.uka.ilkd.key.macros.scripts.ProofScriptCommandFacade; +import de.uka.ilkd.key.proof.Node; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.Statistics; +import de.uka.ilkd.key.util.KeYConstants; +import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.keyproject.key.api.adapters.KeyAdapter; +import org.keyproject.key.api.data.*; +import org.keyproject.key.api.remoteapi.KeyApi; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public record KeyApiImpl(KeyAdapter adapter) implements KeyApi { + + @Override + @JsonRequest + public CompletableFuture> examples() { + return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); + } + + @Override + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(null); + } + + @Override + public void exit() { + } + + @Override + public void setTrace(SetTraceParams params) { + + } + + @Override + public CompletableFuture getVersion() { + return CompletableFuture.completedFuture(KeYConstants.VERSION); + } + + @Override + public CompletableFuture> getAvailableMacros() { + return CompletableFuture.completedFuture( + ProofMacroFacade.instance().getMacros().stream().toList() + ); + } + + @Override + public CompletableFuture>> getAvailableScriptCommands() { + return CompletableFuture.completedFuture( + ProofScriptCommandFacade.instance().getScriptCommands().stream().toList()); + } + + @Override + public CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options) { + return null; + } + + @Override + public CompletableFuture macro(Proof id, String macroId, StreategyOptions options) { + return null; + } + + @Override + public CompletableFuture auto(Proof id, StreategyOptions options) { + return null; + } + + @Override + public CompletableFuture dispose(Proof id) { + return null; + } + + @Override + public CompletableFuture goals(Proof id) { + return null; + } + + @Override + public CompletableFuture tree(Proof proof) { + return null; + } + + @Override + public CompletableFuture root(Proof proof) { + return null; + } + + @Override + public CompletableFuture> children(Proof proof, Node nodeId) { + return null; + } + + @Override + public CompletableFuture> pruneTo(Proof proof, Node nodeId) { + return null; + } + + @Override + public CompletableFuture statistics(Proof proof) { + return null; + } + + @Override + public CompletableFuture treeRoot(Proof proof) { + return null; + } + + @Override + public CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId) { + return null; + } + + @Override + public CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId) { + return null; + } + + @Override + public CompletableFuture> sorts(KeYEnvironment env) { + return null; + } + + @Override + public CompletableFuture> functions(KeYEnvironment env) { + return null; + } + + @Override + public CompletableFuture> contracts(KeYEnvironment env) { + return null; + } + + @Override + public CompletableFuture openContract(KeYEnvironment env, String contractId) { + return null; + } + + @Override + public CompletableFuture print(Node id) { + return null; + } + + @Override + public CompletableFuture> actions(PrintId id, int pos) { + return null; + } + + @Override + public CompletableFuture> applyAction(TermActionId id) { + return null; + } + + @Override + public void freePrint(PrintId id) { + + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index 26837bb84b6..408cc36acdd 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -4,7 +4,7 @@ import com.google.gson.GsonBuilder; import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.websocket.jakarta.WebSocketLauncherBuilder; -import org.keyproject.key.api.remoteapi.KeyApiImpl; +import org.keyproject.key.api.adapters.KeyAdapter; import org.keyproject.key.api.remoteclient.ClientApi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,9 +16,6 @@ import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.concurrent.ExecutionException; /** @@ -29,6 +26,8 @@ public class StartServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); + private static KeyAdapter adapter; + //region CLI arguments @Option(names = "--std", description = "use stdout and stdin for communication") boolean stdStreams; @@ -55,7 +54,7 @@ public class StartServer implements Runnable { boolean helpRequested = false; @Option(names = "--websocket") - boolean websocket; + boolean websocket = false; //endregion public static void main(String[] args) { @@ -115,27 +114,6 @@ public void run() { return; } - /* - var server = new Server(); - var connector = new ServerConnector(); - server.addConnector(connector); - // Setup the basic application "context" for this application at "/" - // This is also known as the handler tree (in jetty speak) - var context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/"); - server.setHandler(context); - - // Initialize javax.websocket layer - JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> - { - // Configure defaults for container - wsContainer.setDefaultMaxTextMessageBufferSize(65535); - - // Add WebSocket endpoint to javax.websocket layer - wsContainer.addEndpoint(WebSocketEndpoint.class); - });*/ - - try { if (websocket) { var launcherBuilder = new WebSocketLauncherBuilder() @@ -144,7 +122,7 @@ public void run() { .traceMessages(new PrintWriter(System.err)) .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - launcherBuilder.setLocalService(new KeyApiImpl()); + launcherBuilder.setLocalService(new KeyApiImpl(adapter)); launcherBuilder.setRemoteInterface(ClientApi.class); launcherBuilder.create().startListening().get(); } else { @@ -160,8 +138,9 @@ public void run() { } } + public static void configureJson(GsonBuilder gsonBuilder) { - gsonBuilder.registerTypeAdapter(File.class, new FileTypeAdapter()); + adapter = new KeyAdapter(gsonBuilder); } public static Launcher launch(OutputStream out, InputStream in) { @@ -174,30 +153,11 @@ public static Launcher launch(OutputStream out, InputStream in) { .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - //if (localServices != null && !localServices.isEmpty()) - launcherBuilder.setLocalService(new KeyApiImpl()); + launcherBuilder.setLocalService(new KeyApiImpl(adapter)); //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) launcherBuilder.setRemoteInterface(ClientApi.class); return launcherBuilder.create(); } - - - private static Collection> getRemoteInterfaces() { - return Collections.singleton(ClientApi.class); - /* return ServiceLoader.load(ClientService.class) - .stream() - .map(ServiceLoader.Provider::type) - .collect(Collectors.toSet()); - */ - } - - private static List getLocalServices() { - return Collections.singletonList(new KeyApiImpl()); - /*return ServiceLoader.load(KeyService.class) - .stream().map(ServiceLoader.Provider::get) - .map(it -> (Object) it) - .toList();*/ - } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java new file mode 100644 index 00000000000..9168a2128f5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -0,0 +1,96 @@ +package org.keyproject.key.api.adapters; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.gson.*; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import de.uka.ilkd.key.Identifiable; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.macros.ProofMacro; +import de.uka.ilkd.key.macros.ProofMacroFacade; +import de.uka.ilkd.key.proof.Proof; +import org.keyproject.key.api.data.MacroDescription; + +import java.io.File; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.lang.reflect.Type; + +/** + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +public class KeyAdapter { + private final BiMap> map = HashBiMap.create(1024); + //private final TypeAdapter adaptor; + + public KeyAdapter(GsonBuilder gson) { + gson.registerTypeAdapter(File.class, new FileTypeAdapter()); + gson.registerTypeAdapter(Function.class, new FunctionTypeAdapter()); + gson.registerTypeAdapter(Proof.class, new IdentifiableTypeAdapter()); + gson.registerTypeAdapter(ProofMacro.class, new MacroTypeAdapter()); + //adaptor = gson.create().getAdapter(Object.class); + } + + + //translating entities to identification strings + public String insert(Identifiable p) { + var id = p.identification(); + if (!map.containsKey(id)) { + map.put(id, new WeakReference<>(p)); + } + return id; + } + + public Object find(String id) { + return map.get(id).get(); + } + //endregion + + class MacroTypeAdapter implements JsonSerializer { + @Override + public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationContext context) { + return context.serialize(MacroDescription.from(src)); + } + } + + class FileTypeAdapter extends TypeAdapter { + @Override + public void write(JsonWriter out, File value) throws IOException { + out.value(value.toString()); + } + + @Override + public File read(JsonReader in) throws IOException { + return new File(in.nextString()); + } + } + + class FunctionTypeAdapter implements JsonSerializer { + @Override + public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationContext context) { + var obj = new JsonObject(); + obj.add("name", context.serialize(src.name().toString())); + obj.add("skolemConstant", context.serialize(src.isSkolemConstant())); + obj.add("isRigid", context.serialize(src.isRigid())); + obj.add("isUnique", context.serialize(src.isUnique())); + obj.add("sort", context.serialize(src.sort())); + obj.add("argSorts", context.serialize(src.argSorts())); + return obj; + } + } + + class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { + @Override + public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return (Identifiable) find(json.getAsString()); + } + + @Override + public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerializationContext context) { + insert(src); + return context.serialize(src.identification()); + } + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java new file mode 100644 index 00000000000..bbc28eec1ec --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java @@ -0,0 +1,7 @@ +/** + * Adapter classes for translating things from Java to JSON via GSON api. + * + * @author Alexander Weigl + * @version 1 (14.10.23) + */ +package org.keyproject.key.api.adapters; \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java new file mode 100644 index 00000000000..a81f8d863db --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record ContractDesc() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java new file mode 100644 index 00000000000..0c612b44cc2 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api.data; + +import java.util.List; + +/** + * @author Alexander Weigl + * @version 1 (15.10.23) + */ +public record FunctionDesc(String name, String sort, List sorts) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java b/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java new file mode 100644 index 00000000000..7a0e2f264e0 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.pp.PositionTable; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record GoalText(PrintId id, String text, PositionTable table) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java new file mode 100644 index 00000000000..85ec900cd57 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java @@ -0,0 +1,14 @@ +package org.keyproject.key.api.data; + +import java.io.File; +import java.util.List; + +/** + * + * @param keyFile + * @param javaFile + * @param classPath + * @param bootClassPath + * @param includes + */ +public record LoadParams(File keyFile, File javaFile, List classPath, File bootClassPath, List includes) {} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java similarity index 72% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java rename to keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java index ad6d12babf8..0274bc38b30 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MacroDescription.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java @@ -1,7 +1,13 @@ -package org.keyproject.key.api.remoteapi; +package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacro; +/** + * + * @param name + * @param description + * @param category + */ public record MacroDescription(String name, String description, String category) { public static MacroDescription from(ProofMacro m) { return new MacroDescription(m.getName(), m.getDescription(), m.getCategory()); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java new file mode 100644 index 00000000000..74c2d9d1cc4 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record MacroStatistic() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java new file mode 100644 index 00000000000..9bc8ad0cd04 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record NodeDesc() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java new file mode 100644 index 00000000000..640c25371d6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (15.10.23) + */ +public record PredicateDesc(String name, String[] argSorts) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java new file mode 100644 index 00000000000..3d4893d43e4 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record PrintId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java new file mode 100644 index 00000000000..4e2de0d4010 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java @@ -0,0 +1,18 @@ +package org.keyproject.key.api.data; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +/** + * @author Alexander Weigl + * @version 1 (15.10.23) + */ +public record ProblemDefinition( + @Nullable List sorts, + @Nullable List functions, + @Nullable List predicates, + @Nullable List antecTerms, + @Nullable List succTerms +) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java new file mode 100644 index 00000000000..14d737fd5d6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java @@ -0,0 +1,42 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + +import java.util.concurrent.CompletableFuture; + +/** + * Functionalities for loading proofs either from a built-in example, or from a set of files. + * + * @author Alexander Weigl + * @since v1 + */ +@JsonSegment("loading") +public interface ProofLoading { + /** + * I am not sure whether this is helpful. Mainly a feature for testing?! + * @param id + * @return + */ + @JsonRequest + CompletableFuture loadExample(String id); + + /** + * + */ + @JsonRequest + CompletableFuture loadProblem(ProblemDefinition problem); + + /** + * Test! + * + * @param params parameters for loading + * @return + * @throws ProblemLoaderException if something went wrong + */ + @JsonRequest + CompletableFuture> load(LoadParams params) throws ProblemLoaderException; +} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java new file mode 100644 index 00000000000..b582b4a73f5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record SortDesc() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java new file mode 100644 index 00000000000..b73ee35b7b5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record StreategyOptions() { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java new file mode 100644 index 00000000000..b69046120f5 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TermAction(TermActionId commandId, String displayName) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java new file mode 100644 index 00000000000..7951c776af4 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TermActionId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java similarity index 54% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java rename to keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java index 567b740d6d8..7f8c9564aa9 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/TraceValue.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java @@ -1,4 +1,4 @@ -package org.keyproject.key.api.remoteapi; +package org.keyproject.key.api.data; public enum TraceValue { Off, Message, All; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java new file mode 100644 index 00000000000..213bb6b9dbe --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public class TreeNodeDesc { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java new file mode 100644 index 00000000000..3dba5cc492e --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TreeNodeId(String id) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java new file mode 100644 index 00000000000..e82ca44ae28 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java @@ -0,0 +1,31 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.proof.Proof; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.ContractDesc; +import org.keyproject.key.api.data.SortDesc; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("env") +public interface EnvApi { + @JsonRequest + CompletableFuture> sorts(KeYEnvironment env); + + @JsonRequest + CompletableFuture> functions(KeYEnvironment env); + + @JsonRequest + CompletableFuture> contracts(KeYEnvironment env); + + @JsonRequest + CompletableFuture openContract(KeYEnvironment env, String contractId); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java deleted file mode 100644 index 3a2b5291d66..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvId.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -/** - * @author Alexander Weigl - * @version 1 (06.10.23) - */ -public record EnvId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java similarity index 91% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java index b1bc064b954..9ccbb03049f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java @@ -8,7 +8,7 @@ import java.util.concurrent.CompletableFuture; @JsonSegment("examples") -public interface KeyExampleApi { +public interface ExampleApi { @JsonRequest("list") CompletableFuture> examples(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java new file mode 100644 index 00000000000..fe678b8f04e --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -0,0 +1,32 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.Node; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.GoalText; +import org.keyproject.key.api.data.PrintId; +import org.keyproject.key.api.data.TermAction; +import org.keyproject.key.api.data.TermActionId; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("goal") +public interface GoalApi { + @JsonRequest + CompletableFuture print(Node id); + + @JsonRequest + CompletableFuture> actions(PrintId id, int pos); + + @JsonRequest("apply_action") + CompletableFuture> applyAction(TermActionId id); + + @JsonNotification("free") + void freePrint(PrintId id); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index 9a6e35fe2eb..ac650359a74 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -1,55 +1,7 @@ package org.keyproject.key.api.remoteapi; -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; - -import java.util.concurrent.CompletableFuture; - -public interface KeyApi extends KeyExampleApi, KeyMetaApi { - //region general server management - /** - * Shutdown Request (:leftwards_arrow_with_hook:) - The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. - - If a server receives requests after a shutdown request those requests should error with InvalidRequest. - - Request: - - method: ‘shutdown’ - params: none - Response: - - result: null - error: code and message set in case an exception happens during shutdown request. - */ - @JsonRequest - CompletableFuture shutdown(); - - /** - * Exit Notification (:arrow_right:) - * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. - *

    - * Notification: - *

    - * method: ‘exit’ - * params: none - */ - @JsonNotification - void exit(); - - - - interface SetTraceParams { - /** - * The new value that should be assigned to the trace setting. - */ - TraceValue value = null; - } - /** - * SetTrace Notification - * A notification that should be used by the client to modify the trace setting of the server. - */ - @JsonNotification - void setTrace(SetTraceParams params); - //endregion +/** + * The combined interface that is provided by KeY. + */ +public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi { } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java deleted file mode 100644 index 33ae9c03aba..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApiImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -import de.uka.ilkd.key.api.KeYApi; -import de.uka.ilkd.key.gui.Example; -import de.uka.ilkd.key.gui.ExampleChooser; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; -import de.uka.ilkd.key.util.KeYConstants; -import org.eclipse.lsp4j.jsonrpc.CompletableFutures; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -@JsonSegment -public class KeyApiImpl implements KeyApi { - @Override - @JsonRequest - public CompletableFuture> examples() { - return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); - } - - @Override - public CompletableFuture shutdown() { - return CompletableFuture.completedFuture(null); - } - - @Override - public void exit() { - - } - - @Override - public void setTrace(SetTraceParams params) { - - } - - @Override - public CompletableFuture getVersion() { - return CompletableFuture.completedFuture(KeYConstants.VERSION); - } - - @Override - public CompletableFuture> getAvailableMacros() { - return CompletableFuture.completedFuture( - KeYApi.getMacroApi().getMacros().stream().map(MacroDescription::from) - .toList() - ); - } - - @Override - public CompletableFuture>> getAvailableScriptCommands() { - return CompletableFuture.completedFuture( - KeYApi.getScriptCommandApi().getScriptCommands().stream().toList()); - } -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java deleted file mode 100644 index 7eadda846ba..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/LoadParams.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -import java.io.File; -import java.util.List; - -public record LoadParams(File keyFile, File javaFile, List classPath, File bootClassPath, List includes) { - -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java similarity index 64% rename from keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java index df0112c51f2..a4a16b66b02 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyMetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java @@ -1,5 +1,6 @@ package org.keyproject.key.api.remoteapi; +import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; @@ -8,13 +9,13 @@ import java.util.concurrent.CompletableFuture; @JsonSegment("meta") -public interface KeyMetaApi { - @JsonRequest +public interface MetaApi { + @JsonRequest("version") CompletableFuture getVersion(); - @JsonRequest - CompletableFuture> getAvailableMacros(); + @JsonRequest("available_macros") + CompletableFuture> getAvailableMacros(); - @JsonRequest + @JsonRequest("available_script_commands") CompletableFuture>> getAvailableScriptCommands(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java new file mode 100644 index 00000000000..16c9f390b89 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java @@ -0,0 +1,48 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.Node; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.Statistics; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.keyproject.key.api.data.MacroStatistic; +import org.keyproject.key.api.data.NodeDesc; +import org.keyproject.key.api.data.StreategyOptions; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public interface ProofApi { + @JsonRequest + CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options); + + @JsonRequest + CompletableFuture macro(Proof proof, String macroId, StreategyOptions options); + + @JsonRequest + CompletableFuture auto(Proof proof, StreategyOptions options); + + @JsonRequest + CompletableFuture dispose(Proof proof); + + @JsonRequest + CompletableFuture goals(Proof proof); + + @JsonRequest + CompletableFuture tree(Proof proof); + + @JsonRequest + CompletableFuture root(Proof proof); + + @JsonRequest + CompletableFuture> children(Proof proof, Node nodeId); + + @JsonRequest + CompletableFuture> pruneTo(Proof proof, Node nodeId); + + @JsonRequest + CompletableFuture statistics(Proof proof); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java deleted file mode 100644 index 7d1d4eb5d6b..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofId.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -public record ProofId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java deleted file mode 100644 index 49081037dc0..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoading.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.keyproject.key.api.remoteapi; - -import de.uka.ilkd.key.proof.io.ProblemLoaderException; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - -@JsonSegment -public interface ProofLoading { - @JsonRequest - ProofId loadExample(String id); - - /** - * @param params - * @return - * @throws ProblemLoaderException - */ - @JsonRequest - EnvId load(LoadParams params) throws ProblemLoaderException; -} \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java new file mode 100644 index 00000000000..88f5cad0330 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java @@ -0,0 +1,26 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.proof.Proof; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.TreeNodeDesc; +import org.keyproject.key.api.data.TreeNodeId; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("proofTree") +public interface ProofTreeApi { + @JsonRequest("root") + CompletableFuture treeRoot(Proof id); + + @JsonRequest("children") + CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId); + + @JsonRequest("subtree") + CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java new file mode 100644 index 00000000000..ddd1fe408e6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java @@ -0,0 +1,60 @@ +package org.keyproject.key.api.remoteapi; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.TraceValue; + +import java.util.concurrent.CompletableFuture; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +@JsonSegment("server") +public interface ServerManagement { + /** + * Shutdown Request (:leftwards_arrow_with_hook:) + * The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. + *

    + * If a server receives requests after a shutdown request those requests should error with InvalidRequest. + *

    + * Request: + *

    + * method: ‘shutdown’ + * params: none + * Response: + *

    + * result: null + * error: code and message set in case an exception happens during shutdown request. + */ + @JsonRequest + CompletableFuture shutdown(); + + /** + * Exit Notification (:arrow_right:) + * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. + *

    + * Notification: + *

    + * method: ‘exit’ + * params: none + */ + @JsonNotification + void exit(); + + + interface SetTraceParams { + /** + * The new value that should be assigned to the trace setting. + */ + TraceValue value = null; + } + + /** + * SetTrace Notification + * A notification that should be used by the client to modify the trace setting of the server. + */ + @JsonNotification + void setTrace(SetTraceParams params); +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java index 6f02b10a186..a7aebdca1bf 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -7,7 +7,7 @@ import javax.annotation.Nullable; import java.util.concurrent.CompletableFuture; -@JsonSegment +@JsonSegment("client") public interface ClientApi { @JsonNotification void sayHello(String e); diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java index 3370f6eb31f..1b63674ce67 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -18,7 +18,7 @@ public void logTrace(LogTraceParams params) { } @Override - public void userResponse(ShowMessageParams params) { + public void showMessage(ShowMessageParams params) { } diff --git a/keyext.api/src/test/java/org/keyproject/key/api/Client.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java similarity index 57% rename from keyext.api/src/test/java/org/keyproject/key/api/Client.java rename to keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index 4922de0993a..edbe4aee393 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/Client.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -2,6 +2,9 @@ import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; @@ -11,13 +14,17 @@ import java.io.PrintWriter; import java.util.Collections; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; -public class Client { - public static void main(String[] args) throws IOException, ExecutionException, InterruptedException, TimeoutException { +public class TestRpc { + private Future clientListening, serverListening; + private KeyApi keyApi; + + @BeforeEach + void setup() throws IOException, ExecutionException, InterruptedException, TimeoutException { PipedInputStream inClient = new PipedInputStream(); PipedOutputStream outClient = new PipedOutputStream(); PipedInputStream inServer = new PipedInputStream(); @@ -41,13 +48,33 @@ public static void main(String[] args) throws IOException, ExecutionException, I Logger logger = Logger.getLogger(StreamMessageProducer.class.getName()); logger.setLevel(Level.SEVERE); - var clientListening = clientLauncher.startListening(); - var serverListening = serverLauncher.startListening(); + clientListening = clientLauncher.startListening(); + serverListening = serverLauncher.startListening(); + + keyApi = clientLauncher.getRemoteProxy(); + } + + @AfterEach + void teardown() throws ExecutionException, InterruptedException, TimeoutException { + serverListening.cancel(true); + clientListening.cancel(true); + } + + + @Test + public void hello() { - //clientLauncher.getRemoteProxy().examples(); - serverLauncher.getRemoteProxy().sayHello("Alex"); + } + + @Test + public void listMacros() throws ExecutionException, InterruptedException { + var examples = keyApi.getAvailableMacros().get(); + System.out.println(examples); + } - serverListening.get(1, TimeUnit.SECONDS); - clientListening.get(1, TimeUnit.SECONDS); + @Test + public void listExamples() throws ExecutionException, InterruptedException { + var examples = keyApi.examples().get(); + System.out.println(examples); } } diff --git a/settings.gradle b/settings.gradle index a7fccaa51b6..f2d7206d797 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,3 +15,4 @@ include 'keyext.exploration' include 'keyext.slicing' include 'keyext.api' +include 'keyext.api.doc' From acfeada8cf333a9099d0be963e3da9405c11ea1c Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 29 Oct 2023 16:45:43 +0100 Subject: [PATCH 14/50] working on a working minimal version --- .../src/main/java/org/key_project/Main.java | 3 +- .../AbstractSymbolicExecutionTestCase.java | 1636 +++++++++-------- .../java/de/uka/ilkd/key/Identifiable.java | 11 - .../key/control/AbstractProofControl.java | 13 +- .../ilkd/key/control/DefaultProofControl.java | 51 +- .../de/uka/ilkd/key/control/ProofControl.java | 10 +- .../key/macros/ProofMacroFinishedInfo.java | 1 + .../ilkd/key/macros/ProofMacroListener.java | 2 +- .../main/java/de/uka/ilkd/key/proof/Node.java | 79 +- .../java/de/uka/ilkd/key/proof/Proof.java | 12 +- .../ilkd/key/proof/io/TestZipProofSaving.java | 2 +- .../de/uka/ilkd/key/gui/ProofMacroWorker.java | 39 +- .../uka/ilkd/key/gui/ProofScriptWorker.java | 7 + .../key/gui/actions/RunAllProofsAction.java | 25 +- .../key/ui/ConsoleUserInterfaceControl.java | 8 +- .../uka/ilkd/key/ui/MediatorProofControl.java | 22 +- .../org/keyproject/key/api/KeyApiImpl.java | 487 ++++- .../org/keyproject/key/api/NodeTextDesc.java | 8 + .../org/keyproject/key/api/NodeTextId.java | 10 + .../org/keyproject/key/api/StartServer.java | 16 +- .../keyproject/key/api/TermActionUtil.java | 125 ++ .../key/api/adapters/KeyAdapter.java | 29 +- .../keyproject/key/api/data/ContractDesc.java | 11 +- .../keyproject/key/api/data/FunctionDesc.java | 13 +- .../org/keyproject/key/api/data/GoalText.java | 10 - .../key/api/data/KeyIdentifications.java | 163 ++ .../key/api/data/MacroStatistic.java | 9 +- .../org/keyproject/key/api/data/NodeDesc.java | 12 +- .../org/keyproject/key/api/data/PrintId.java | 8 - .../key/api/data/ProofMacroDesc.java | 14 + .../key/api/data/ProofScriptCommandDesc.java | 13 + .../org/keyproject/key/api/data/SortDesc.java | 13 +- .../keyproject/key/api/data/TermAction.java | 8 - .../key/api/data/TermActionDesc.java | 11 + .../keyproject/key/api/data/TermActionId.java | 6 - .../key/api/data/TermActionKind.java | 9 + .../keyproject/key/api/data/TreeNodeId.java | 6 - .../keyproject/key/api/internal/NodeText.java | 12 + .../keyproject/key/api/remoteapi/EnvApi.java | 13 +- .../keyproject/key/api/remoteapi/GoalApi.java | 17 +- .../keyproject/key/api/remoteapi/KeyApi.java | 2 +- .../keyproject/key/api/remoteapi/MetaApi.java | 9 +- .../key/api/remoteapi/PrintOptions.java | 9 + .../key/api/remoteapi/ProofApi.java | 23 +- .../ProofLoadApi.java} | 25 +- .../key/api/remoteapi/ProofTreeApi.java | 10 +- .../key/api/remoteclient/ClientApi.java | 7 + .../org/keyproject/key/api/SimpleClient.java | 17 + .../java/org/keyproject/key/api/TestRpc.java | 7 +- .../ProofExplorationServiceTest.java | 47 +- 50 files changed, 2000 insertions(+), 1100 deletions(-) delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/Identifiable.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java rename keyext.api/src/main/java/org/keyproject/key/api/{data/ProofLoading.java => remoteapi/ProofLoadApi.java} (50%) diff --git a/key.core.example/src/main/java/org/key_project/Main.java b/key.core.example/src/main/java/org/key_project/Main.java index 51ba6c5547d..4da18d230e9 100644 --- a/key.core.example/src/main/java/org/key_project/Main.java +++ b/key.core.example/src/main/java/org/key_project/Main.java @@ -92,6 +92,7 @@ private static void proveEnvironmemt(KeYEnvironment env) { for (Contract contract : proofContracts) { proveContract(env, contract); } + } catch (InterruptedException ignored) { } finally { env.dispose(); // Ensure always that all instances of KeYEnvironment are disposed } @@ -130,7 +131,7 @@ private static List getContracts(KeYEnvironment env) { * @param env the {@link KeYEnvironment} in which to prove the contract * @param contract the {@link Contract} to be proven */ - private static void proveContract(KeYEnvironment env, Contract contract) { + private static void proveContract(KeYEnvironment env, Contract contract) throws InterruptedException { Proof proof = null; try { // Create proof diff --git a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java index 95c6da8fe33..907a15d5c9d 100644 --- a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java +++ b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java @@ -44,7 +44,6 @@ import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionUtil; import de.uka.ilkd.key.util.HelperClassForTests; import de.uka.ilkd.key.util.KeYConstants; - import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableList; @@ -52,11 +51,15 @@ import org.key_project.util.helper.FindResources; import org.key_project.util.java.CollectionUtil; import org.key_project.util.java.StringUtil; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.IOException; +import java.util.*; + import static org.junit.jupiter.api.Assertions.*; /** @@ -66,7 +69,7 @@ */ public abstract class AbstractSymbolicExecutionTestCase { private static final Logger LOGGER = - LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); + LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); /** *

    @@ -83,7 +86,7 @@ public abstract class AbstractSymbolicExecutionTestCase { *

    */ public static final boolean CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY = - Boolean.getBoolean("UPDATE_TEST_ORACLE"); + Boolean.getBoolean("UPDATE_TEST_ORACLE"); static { @@ -99,13 +102,13 @@ public abstract class AbstractSymbolicExecutionTestCase { * Number of executed SET nodes to execute all in one. */ public static final int ALL_IN_ONE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; /** * Number of executed SET nodes for only one SET node per auto mode run. */ public static final int SINGLE_SET_NODE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; /** * Default stop conditions of executed SET nodes. @@ -132,9 +135,9 @@ public abstract class AbstractSymbolicExecutionTestCase { static { // Define fast mode if (FAST_MODE) { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN }; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN}; } else { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN }; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN}; } // Create temporary director for oracle files if required. File directory = null; @@ -157,18 +160,18 @@ public abstract class AbstractSymbolicExecutionTestCase { /** * Creates a new oracle file. * - * @param node The node to save as oracle file. + * @param node The node to save as oracle file. * @param oraclePathInBaseDirFile The path in example directory. - * @param saveConstraints Save constraints? - * @param saveVariables Save variables? - * @param saveCallStack Save call stack? - * @param saveReturnValues Save method return values? - * @throws IOException Occurred Exception + * @param saveConstraints Save constraints? + * @param saveVariables Save variables? + * @param saveCallStack Save call stack? + * @param saveReturnValues Save method return values? + * @throws IOException Occurred Exception * @throws ProofInputException Occurred Exception */ protected static void createOracleFile(IExecutionNode node, String oraclePathInBaseDirFile, - boolean saveConstraints, boolean saveVariables, boolean saveCallStack, - boolean saveReturnValues) throws IOException, ProofInputException { + boolean saveConstraints, boolean saveVariables, boolean saveCallStack, + boolean saveReturnValues) throws IOException, ProofInputException { if (tempNewOracleDirectory != null && tempNewOracleDirectory.isDirectory()) { // Create sub folder structure File oracleFile = new File(tempNewOracleDirectory, oraclePathInBaseDirFile); @@ -176,7 +179,7 @@ protected static void createOracleFile(IExecutionNode node, String oraclePath // Create oracle file ExecutionNodeWriter writer = new ExecutionNodeWriter(); writer.write(node, ExecutionNodeWriter.DEFAULT_ENCODING, oracleFile, saveVariables, - saveCallStack, saveReturnValues, saveConstraints); + saveCallStack, saveReturnValues, saveConstraints); // Print message to the user. printOracleDirectory(); } @@ -204,37 +207,37 @@ protected static void printOracleDirectory() { /** * Makes sure that the given nodes and their subtrees contains the same content. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? - * @param compareChildOrder Is the order of children relevant? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? + * @param compareChildOrder Is the order of children relevant? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { if (compareChildOrder) { // Order of children must be the same. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { // Order of children is not relevant. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); Set> currentVisitedNodes = new LinkedHashSet<>(); while (expectedExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); @@ -243,11 +246,11 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo fail("Node " + currentNext + " visited twice."); } assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } // Make sure that each current node was visited ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); if (!currentVisitedNodes.remove(currentNext)) { @@ -261,13 +264,13 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo /** * Searches the direct or indirect child in subtree of the node to search in. * - * @param toSearchIn The node to search in. + * @param toSearchIn The node to search in. * @param childToSearch The node to search. * @return The found node. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearchIn, - IExecutionNode childToSearch) throws ProofInputException { + IExecutionNode childToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(toSearchIn); assertNotNull(childToSearch); @@ -288,20 +291,20 @@ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearc } } assertNotNull(toSearchIn, "Direct or indirect Child " + childToSearch - + " is not contained in " + toSearchIn + "."); + + " is not contained in " + toSearchIn + "."); return toSearchIn; } /** * Searches the direct child. Nodes are equal if the name and the element type is equal. * - * @param parentToSearchIn The parent to search in its children. + * @param parentToSearchIn The parent to search in its children. * @param directChildToSearch The child to search. * @return The found child. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchDirectChildNode(IExecutionNode parentToSearchIn, - IExecutionNode directChildToSearch) throws ProofInputException { + IExecutionNode directChildToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(parentToSearchIn); assertNotNull(directChildToSearch); @@ -315,60 +318,60 @@ protected static IExecutionNode searchDirectChildNode(IExecutionNode paren if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) directChildToSearch) - .getAdditionalBranchLabel()) + ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) directChildToSearch) + .getAdditionalBranchLabel()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } else { if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } i++; } assertNotNull(result, - "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); + "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); return result; } /** * Makes sure that the given nodes contains the same content. Children are not compared. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareParent Compare also the parent node? - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareParent Compare also the parent node? + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertExecutionNode(IExecutionNode expected, IExecutionNode current, - boolean compareParent, boolean compareVariables, boolean compareCallStack, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareParent, boolean compareVariables, boolean compareCallStack, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { // Compare nodes assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); + "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); assertEquals(expected.isPathConditionChanged(), current.isPathConditionChanged()); if (!StringUtil.equalIgnoreWhiteSpace(expected.getFormatedPathCondition(), - current.getFormatedPathCondition())) { + current.getFormatedPathCondition())) { assertEquals(expected.getFormatedPathCondition(), current.getFormatedPathCondition()); } if (compareParent) { if (expected instanceof IExecutionBlockStartNode) { assertTrue(current instanceof IExecutionBlockStartNode); assertEquals(((IExecutionBlockStartNode) expected).isBlockOpened(), - ((IExecutionBlockStartNode) current).isBlockOpened()); + ((IExecutionBlockStartNode) current).isBlockOpened()); assertBlockCompletions((IExecutionBlockStartNode) expected, - (IExecutionBlockStartNode) current); + (IExecutionBlockStartNode) current); } assertCompletedBlocks(expected, current); assertOutgoingLinks(expected, current); @@ -377,177 +380,177 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution if (expected instanceof IExecutionBaseMethodReturn) { assertTrue(current instanceof IExecutionBaseMethodReturn); assertCallStateVariables((IExecutionBaseMethodReturn) expected, - (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); + (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); } if (expected instanceof IExecutionBranchCondition) { assertTrue(current instanceof IExecutionBranchCondition, - "Expected IExecutionBranchCondition but is " + current.getClass() + "."); + "Expected IExecutionBranchCondition but is " + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), - ((IExecutionBranchCondition) current).getFormatedBranchCondition()), - "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), + ((IExecutionBranchCondition) current).getFormatedBranchCondition()), + "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); assertEquals(((IExecutionBranchCondition) expected).isMergedBranchCondition(), - ((IExecutionBranchCondition) current).isMergedBranchCondition()); + ((IExecutionBranchCondition) current).isMergedBranchCondition()); assertEquals(((IExecutionBranchCondition) expected).isBranchConditionComputed(), - ((IExecutionBranchCondition) current).isBranchConditionComputed()); + ((IExecutionBranchCondition) current).isBranchConditionComputed()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), - "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), + "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStart) { assertTrue(current instanceof IExecutionStart, "Expected IExecutionStartNode but is " - + current.getClass() + "."); + + current.getClass() + "."); assertTerminations((IExecutionStart) expected, (IExecutionStart) current); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionTermination) { assertTrue(current instanceof IExecutionTermination, - "Expected IExecutionTermination but is " - + current.getClass() + "."); + "Expected IExecutionTermination but is " + + current.getClass() + "."); assertEquals(((IExecutionTermination) expected).getTerminationKind(), - ((IExecutionTermination) current).getTerminationKind()); + ((IExecutionTermination) current).getTerminationKind()); assertEquals(((IExecutionTermination) expected).isBranchVerified(), - ((IExecutionTermination) current).isBranchVerified()); + ((IExecutionTermination) current).isBranchVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionBranchStatement) { assertTrue(current instanceof IExecutionBranchStatement, - "Expected IExecutionBranchStatement but is " - + current.getClass() + "."); + "Expected IExecutionBranchStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopCondition) { assertTrue(current instanceof IExecutionLoopCondition, - "Expected IExecutionLoopCondition but is " - + current.getClass() + "."); + "Expected IExecutionLoopCondition but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopStatement) { assertTrue(current instanceof IExecutionLoopStatement, - "Expected IExecutionLoopStatement but is " - + current.getClass() + "."); + "Expected IExecutionLoopStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionMethodCall) { assertTrue(current instanceof IExecutionMethodCall, - "Expected IExecutionMethodCall but is " - + current.getClass() + "."); + "Expected IExecutionMethodCall but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); assertMethodReturns((IExecutionMethodCall) expected, (IExecutionMethodCall) current); } else if (expected instanceof IExecutionMethodReturn) { assertTrue(current instanceof IExecutionMethodReturn, - "Expected IExecutionMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), - ((IExecutionMethodReturn) current).getSignature()), - ((IExecutionMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), + ((IExecutionMethodReturn) current).getSignature()), + ((IExecutionMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionMethodReturn) current).getSignature()); if (compareReturnValues) { assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), - ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), - ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); assertEquals(((IExecutionMethodReturn) expected).isReturnValuesComputed(), - ((IExecutionMethodReturn) current).isReturnValuesComputed()); + ((IExecutionMethodReturn) current).isReturnValuesComputed()); } assertTrue( - StringUtil.equalIgnoreWhiteSpace( + StringUtil.equalIgnoreWhiteSpace( ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + + " does not match " + ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); if (compareReturnValues) { assertReturnValues(((IExecutionMethodReturn) expected).getReturnValues(), - ((IExecutionMethodReturn) current).getReturnValues()); + ((IExecutionMethodReturn) current).getReturnValues()); } } else if (expected instanceof IExecutionExceptionalMethodReturn) { assertTrue(current instanceof IExecutionExceptionalMethodReturn, - "Expected IExecutionExceptionalMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionExceptionalMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionExceptionalMethodReturn) expected).getSignature(), - ((IExecutionExceptionalMethodReturn) current).getSignature()), - ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionExceptionalMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionExceptionalMethodReturn) expected).getSignature(), + ((IExecutionExceptionalMethodReturn) current).getSignature()), + ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionExceptionalMethodReturn) current).getSignature()); assertTrue(StringUtil.equalIgnoreWhiteSpace( ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionExceptionalMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + ((IExecutionExceptionalMethodReturn) current) + + " does not match " + ((IExecutionExceptionalMethodReturn) current) .getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStatement) { assertTrue(current instanceof IExecutionStatement, - "Expected IExecutionStatement but is " - + current.getClass() + "."); + "Expected IExecutionStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionOperationContract) { assertTrue(current instanceof IExecutionOperationContract, - "Expected IExecutionOperationContract but is " - + current.getClass() + "."); + "Expected IExecutionOperationContract but is " + + current.getClass() + "."); assertEquals(((IExecutionOperationContract) expected).isPreconditionComplied(), - ((IExecutionOperationContract) current).isPreconditionComplied()); + ((IExecutionOperationContract) current).isPreconditionComplied()); assertEquals(((IExecutionOperationContract) expected).hasNotNullCheck(), - ((IExecutionOperationContract) current).hasNotNullCheck()); + ((IExecutionOperationContract) current).hasNotNullCheck()); assertEquals(((IExecutionOperationContract) expected).isNotNullCheckComplied(), - ((IExecutionOperationContract) current).isNotNullCheckComplied()); + ((IExecutionOperationContract) current).isNotNullCheckComplied()); assertEquals(((IExecutionOperationContract) expected).getFormatedResultTerm(), - ((IExecutionOperationContract) current).getFormatedResultTerm()); + ((IExecutionOperationContract) current).getFormatedResultTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedExceptionTerm(), - ((IExecutionOperationContract) current).getFormatedExceptionTerm()); + ((IExecutionOperationContract) current).getFormatedExceptionTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedSelfTerm(), - ((IExecutionOperationContract) current).getFormatedSelfTerm()); + ((IExecutionOperationContract) current).getFormatedSelfTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedContractParams(), - ((IExecutionOperationContract) current).getFormatedContractParams()); + ((IExecutionOperationContract) current).getFormatedContractParams()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopInvariant) { assertTrue(current instanceof IExecutionLoopInvariant, - "Expected IExecutionLoopInvariant but is " - + current.getClass() + "."); + "Expected IExecutionLoopInvariant but is " + + current.getClass() + "."); assertEquals(((IExecutionLoopInvariant) expected).isInitiallyValid(), - ((IExecutionLoopInvariant) current).isInitiallyValid()); + ((IExecutionLoopInvariant) current).isInitiallyValid()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionAuxiliaryContract) { assertTrue(current instanceof IExecutionAuxiliaryContract, - "Expected IExecutionBlockContract but is " - + current.getClass() + "."); + "Expected IExecutionBlockContract but is " + + current.getClass() + "."); assertEquals(((IExecutionAuxiliaryContract) expected).isPreconditionComplied(), - ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); + ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionJoin) { assertTrue(current instanceof IExecutionJoin, "Expected IExecutionJoin but is " - + current.getClass() + "."); + + current.getClass() + "."); assertEquals(((IExecutionJoin) expected).isWeakeningVerified(), - ((IExecutionJoin) current).isWeakeningVerified()); + ((IExecutionJoin) current).isWeakeningVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else { @@ -559,22 +562,22 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution IExecutionNode[] currentStack = current.getCallStack(); if (expectedStack != null) { assertNotNull(currentStack, - "Call stack of \"" + current + "\" should not be null."); + "Call stack of \"" + current + "\" should not be null."); assertEquals(expectedStack.length, currentStack.length, "Node: " + expected); for (int i = 0; i < expectedStack.length; i++) { assertExecutionNode(expectedStack[i], currentStack[i], false, false, false, - false, false); + false, false); } } else { assertTrue(currentStack == null || currentStack.length == 0, - "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) - + "\" but should be null or empty."); + "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) + + "\" but should be null or empty."); } } // Optionally compare parent if (compareParent) { assertExecutionNode(expected, current, false, compareVariables, compareCallStack, - compareReturnValues, compareConstraints); + compareReturnValues, compareConstraints); } } @@ -582,7 +585,7 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution * Compares the outgoing links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertOutgoingLinks(IExecutionNode expected, IExecutionNode current) @@ -591,9 +594,9 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getOutgoingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Outgoing links of \"" + current + "\" should not be null."); + "Outgoing links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Outgoing links: " + expected); + "Outgoing links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -601,15 +604,15 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Outgoing links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -617,7 +620,7 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution * Compares the incoming links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertIncomingLinks(IExecutionNode expected, IExecutionNode current) @@ -626,9 +629,9 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getIncomingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Incoming links of \"" + current + "\" should not be null."); + "Incoming links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Incoming links: " + expected); + "Incoming links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -636,15 +639,15 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Incoming links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -652,29 +655,29 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution * Compares the completed blocks. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertCompletedBlocks(IExecutionNode expected, - IExecutionNode current) throws ProofInputException { + IExecutionNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getCompletedBlocks(); ImmutableList> currentEntries = current.getCompletedBlocks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Completed blocks of \"" + current + "\" should not be null."); + "Completed blocks of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionBlockStartNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionBlockStartNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, false, false, - false, false, false); + false, false, false); String expectedCondition = - expected.getFormatedBlockCompletionCondition(expectedNext); + expected.getFormatedBlockCompletionCondition(expectedNext); String currentCondition = current.getFormatedBlockCompletionCondition(currentNext); if (!StringUtil.equalIgnoreWhiteSpace(expectedCondition, currentCondition)) { assertEquals(expectedCondition, currentCondition); @@ -684,8 +687,8 @@ protected static void assertCompletedBlocks(IExecutionNode expected, assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Completed block entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Completed block entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -693,33 +696,33 @@ protected static void assertCompletedBlocks(IExecutionNode expected, * Compares the block completions. * * @param expected The expected {@link IExecutionBlockStartNode}. - * @param current The current {@link IExecutionBlockStartNode}. + * @param current The current {@link IExecutionBlockStartNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertBlockCompletions(IExecutionBlockStartNode expected, - IExecutionBlockStartNode current) throws ProofInputException { + IExecutionBlockStartNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getBlockCompletions(); ImmutableList> currentEntries = current.getBlockCompletions(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Block completions of \"" + current + "\" should not be null."); + "Block completions of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Block completion entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Block completion entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -727,34 +730,34 @@ protected static void assertBlockCompletions(IExecutionBlockStartNode expecte * Compares the method returns. * * @param expected The expected {@link IExecutionMethodCall}. - * @param current The current {@link IExecutionMethodCall}. + * @param current The current {@link IExecutionMethodCall}. * @throws ProofInputException Occurred Exception. */ protected static void assertMethodReturns(IExecutionMethodCall expected, - IExecutionMethodCall current) throws ProofInputException { + IExecutionMethodCall current) throws ProofInputException { ImmutableList> expectedEntries = expected.getMethodReturns(); ImmutableList> currentEntries = current.getMethodReturns(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Method return of \"" + current + "\" should not be null."); + "Method return of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Method return entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Method return entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -762,7 +765,7 @@ protected static void assertMethodReturns(IExecutionMethodCall expected, * Compares the terminations. * * @param expected The expected {@link IExecutionStart}. - * @param current The current {@link IExecutionStart}. + * @param current The current {@link IExecutionStart}. * @throws ProofInputException Occurred Exception. */ protected static void assertTerminations(IExecutionStart expected, IExecutionStart current) @@ -773,22 +776,22 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta assertNotNull(currentEntries, "Termination of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Termination entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Termination entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -796,11 +799,11 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta * Makes sure that the given nodes contains the same {@link IExecutionMethodReturnValue}s. * * @param expected The expected {@link IExecutionMethodReturnValue}s. - * @param current The current {@link IExecutionMethodReturnValue}s. + * @param current The current {@link IExecutionMethodReturnValue}s. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, - IExecutionMethodReturnValue[] current) throws ProofInputException { + IExecutionMethodReturnValue[] current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertEquals(expected.length, current.length); @@ -813,36 +816,36 @@ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, * Makes sure that the given {@link IExecutionMethodReturnValue}s are the same. * * @param expected The expected {@link IExecutionMethodReturnValue}. - * @param current The current {@link IExecutionMethodReturnValue}. + * @param current The current {@link IExecutionMethodReturnValue}. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValue(IExecutionMethodReturnValue expected, - IExecutionMethodReturnValue current) throws ProofInputException { + IExecutionMethodReturnValue current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), - current.getReturnValueString()), - expected.getReturnValueString() + " does not match " + current.getReturnValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), + current.getReturnValueString()), + expected.getReturnValueString() + " does not match " + current.getReturnValueString()); assertEquals(expected.hasCondition(), current.hasCondition()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); } /** * Makes sure that the given nodes contains the same {@link IExecutionNode}s. * - * @param expected The expected node. - * @param current The current node. + * @param expected The expected node. + * @param current The current node. * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionNode expected, IExecutionNode current, - boolean compareConstraints) throws ProofInputException { + boolean compareConstraints) throws ProofInputException { if (compareConstraints) { assertNotNull(expected); assertNotNull(current); @@ -856,26 +859,26 @@ protected static void assertConstraints(IExecutionNode expected, IExecutionNo * Makes sure that the given constraints are the same. * * @param expected The expected constraints. - * @param current The current constraints. + * @param current The current constraints. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionConstraint[] expected, - IExecutionConstraint[] current) throws ProofInputException { + IExecutionConstraint[] current) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionConstraint expectedVariable : expected) { // Find current variable with same name IExecutionConstraint currentVariable = CollectionUtil.searchAndRemove( - availableCurrentVariables, element -> { - try { - return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); - } catch (ProofInputException e) { - throw new RuntimeException(e); - } - }); + availableCurrentVariables, element -> { + try { + return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), + element.getName()); + } catch (ProofInputException e) { + throw new RuntimeException(e); + } + }); assertNotNull(currentVariable); // Compare variables assertConstraint(expectedVariable, currentVariable); @@ -887,11 +890,11 @@ protected static void assertConstraints(IExecutionConstraint[] expected, * Makes sure that the given constraints are the same. * * @param expected The expected constraint. - * @param current The current constraint. + * @param current The current constraint. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraint(IExecutionConstraint expected, - IExecutionConstraint current) throws ProofInputException { + IExecutionConstraint current) throws ProofInputException { if (expected != null) { assertNotNull(current); if (!StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName())) { @@ -906,15 +909,15 @@ protected static void assertConstraint(IExecutionConstraint expected, * Makes sure that the given nodes contains the same {@link IExecutionVariable}s of the call * state. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertCallStateVariables(IExecutionBaseMethodReturn expected, - IExecutionBaseMethodReturn current, boolean compareVariables, - boolean compareConstraints) throws ProofInputException { + IExecutionBaseMethodReturn current, boolean compareVariables, + boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -927,14 +930,14 @@ protected static void assertCallStateVariables(IExecutionBaseMethodReturn exp /** * Makes sure that the given nodes contains the same {@link IExecutionVariable}s. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -947,27 +950,27 @@ protected static void assertVariables(IExecutionNode expected, IExecutionNode /** * Makes sure that the given variables are the same. * - * @param expected The expected variables. - * @param current The current variables. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variables. + * @param current The current variables. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionVariable[] expected, - IExecutionVariable[] current, boolean compareParent, boolean compareChildren, - boolean compareConstraints) throws ProofInputException { + IExecutionVariable[] current, boolean compareParent, boolean compareChildren, + boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionVariable expectedVariable : expected) { // Find current variable with same name IExecutionVariable currentVariable = CollectionUtil .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); + element.getName()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -975,7 +978,7 @@ protected static void assertVariables(IExecutionVariable[] expected, assertNotNull(currentVariable); // Compare variables assertVariable(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -983,15 +986,15 @@ protected static void assertVariables(IExecutionVariable[] expected, /** * Makes sure that the given variables are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariable(IExecutionVariable expected, IExecutionVariable current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); @@ -1002,7 +1005,7 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari // Compare parent if (compareParent) { assertValue(expected.getParentValue(), current.getParentValue(), false, false, - false); + false); } // Compare children if (compareChildren) { @@ -1018,15 +1021,15 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari /** * Makes sure that the given values are the same. * - * @param expected The expected values. - * @param current The current values. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected values. + * @param current The current values. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order @@ -1037,10 +1040,10 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()) + element.getName()) && StringUtil.equalIgnoreWhiteSpace( - expectedVariable.getConditionString(), - element.getConditionString()); + expectedVariable.getConditionString(), + element.getConditionString()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -1048,7 +1051,7 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] assertNotNull(currentVariable); // Compare variables assertValue(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -1056,43 +1059,43 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] /** * Makes sure that the given values are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValue(IExecutionValue expected, IExecutionValue current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); // Compare variable assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertEquals(expected.getTypeString(), current.getTypeString()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), - current.getValueString()), - expected.getValueString() + " does not match " + current.getValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), + current.getValueString()), + expected.getValueString() + " does not match " + current.getValueString()); assertEquals(expected.isValueAnObject(), current.isValueAnObject()); assertEquals(expected.isValueUnknown(), current.isValueUnknown()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); // Compare parent if (compareParent) { assertVariable(expected.getVariable(), current.getVariable(), false, false, - compareConstraints); + compareConstraints); } // Compare children if (compareChildren) { IExecutionVariable[] expectedChildVariables = expected.getChildVariables(); IExecutionVariable[] currentChildVariables = current.getChildVariables(); assertVariables(expectedChildVariables, currentChildVariables, compareParent, - compareChildren, compareConstraints); + compareChildren, compareConstraints); } // Compare constraints if (compareConstraints) { @@ -1109,37 +1112,41 @@ protected static void assertValue(IExecutionValue expected, IExecutionValue curr * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturn(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + try { + ui.getProofControl().startAndWaitForAutoMode(proof); + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } @@ -1147,164 +1154,182 @@ protected static void stepReturn(DefaultUserInterfaceControl ui, * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); stopCondition.addChildren(lineBreakpoints); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); - // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + try { + // Run proof + ui.getProofControl().startAndWaitForAutoMode(proof); + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Executes a "step over" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepOver(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepOverSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); - // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + try { + // Run proof + ui.getProofControl().startAndWaitForAutoMode(proof); + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. * @return The found {@link SymbolicExecutionCompletions}. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - SymbolicExecutionCompletions completions = builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); - return completions; + try { + ui.getProofControl().startAndWaitForAutoMode(proof); + + // Update symbolic execution tree + SymbolicExecutionCompletions completions = builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, + baseDir); + return completions; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void resume(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof - ui.getProofControl().startAndWaitForAutoMode(proof); - // Update symbolic execution tree - builder.analyse(); - // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, baseDir); + try { + ui.getProofControl().startAndWaitForAutoMode(proof); + + // Update symbolic execution tree + builder.analyse(); + // Test result + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, baseDir); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, File baseDir) + String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { if (CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { createOracleFile(builder.getStartNode(), oraclePathInBaseDirFile, false, false, false, - false); + false); } else { // Read oracle file File oracleFile = new File(baseDir, oraclePathInBaseDirFile); @@ -1313,41 +1338,41 @@ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builde assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, builder.getStartNode(), false, false, false, false, - false); + false); } } /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, - File baseDir) + String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, + File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { assertSetTreeAfterStep(builder, - oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); + oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); } /** * Searches a {@link IProgramMethod} in the given {@link Services}. * - * @param services The {@link Services} to search in. + * @param services The {@link Services} to search in. * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. + * @param methodFullName The method name to search. * @return The first found {@link IProgramMethod} in the type. */ public static IProgramMethod searchProgramMethod(Services services, String containerTypeName, - final String methodFullName) { + final String methodFullName) { return HelperClassForTests.searchProgramMethod(services, containerTypeName, methodFullName); } @@ -1356,29 +1381,29 @@ public static IProgramMethod searchProgramMethod(Services services, String conta * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param baseContractName The name of the contract. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param baseContractName The name of the contract. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String baseContractName, @@ -1392,26 +1417,26 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, - null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, + null, null, null, true); setupTacletOptions(environment); // Start proof final Contract contract = environment.getServices().getSpecificationRepository() .getContractByName(baseContractName); assertTrue(contract instanceof FunctionalOperationContract); ProofOblInput input = new FunctionalOperationContractPO(environment.getInitConfig(), - (FunctionalOperationContract) contract, true, true); + (FunctionalOperationContract) contract, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1423,30 +1448,30 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1460,25 +1485,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodPO(environment.getInitConfig(), pm.getFullName(), pm, - precondition, true, true); + precondition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1501,26 +1526,26 @@ private static void setupTacletOptions(KeYEnvironment env) { * Creates a {@link SymbolicExecutionEnvironment} which consists of loading a proof file to load * and creation with configuration of {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param proofPathInBaseDir The path to the proof file inside the base directory. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofPathInBaseDir The path to the proof file inside the base directory. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. */ @@ -1537,20 +1562,20 @@ protected static SymbolicExecutionEnvironment creat assertTrue(proofFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, - null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, + null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); setupTacletOptions(environment); Proof proof = environment.getLoadedProof(); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1562,32 +1587,32 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param startPosition The start position. - * @param endPosition The end position. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param startPosition The start position. + * @param endPosition The end position. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1602,25 +1627,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodSubsetPO(environment.getInitConfig(), methodFullName, - pm, precondition, startPosition, endPosition, true, true); + pm, precondition, startPosition, endPosition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1645,7 +1670,7 @@ protected String getTryContent(Proof proof) { JavaProgramElement updateContent = updateApplication.subs().get(1).javaBlock().program(); assertTrue(updateContent instanceof StatementBlock); ImmutableArray updateContentBody = - ((StatementBlock) updateContent).getBody(); + ((StatementBlock) updateContent).getBody(); assertEquals(2, updateContentBody.size()); assertTrue(updateContentBody.get(1) instanceof Try); Try tryStatement = (Try) updateContentBody.get(1); @@ -1656,39 +1681,39 @@ protected String getTryContent(Proof proof) { /** * Makes sure that the save and loading process works. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. * @param oraclePathInBaseDirFile The oracle path. - * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof - * to save/load. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof + * to save/load. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, - String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) + String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) throws IOException, ProofInputException, ParserConfigurationException, SAXException, ProblemLoaderException { File javaFile = new File(baseDir, javaPathInBaseDir); assertTrue(javaFile.exists()); File tempFile = - File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); + File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); KeYEnvironment reloadedEnv = null; SymbolicExecutionTreeBuilder reloadedBuilder = null; try { ProofSaver saver = new ProofSaver(env.getProof(), tempFile.getAbsolutePath(), - KeYConstants.INTERNAL_VERSION); + KeYConstants.INTERNAL_VERSION); assertNull(saver.save()); // Load proof from saved *.proof file reloadedEnv = KeYEnvironment.load(SymbolicExecutionJavaProfile.getDefaultInstance(), - tempFile, null, null, null, true); + tempFile, null, null, null, true); Proof reloadedProof = reloadedEnv.getLoadedProof(); assertNotSame(env.getProof(), reloadedProof); // Recreate symbolic execution tree reloadedBuilder = - new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); + new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); SymbolicExecutionUtil.initializeStrategy(reloadedBuilder); reloadedBuilder.analyse(); assertSetTreeAfterStep(reloadedBuilder, oraclePathInBaseDirFile, baseDir); @@ -1717,59 +1742,59 @@ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? * @param maximalNumberOfExecutedSetNodesPerRun The number of executed set nodes per auto mode - * run. The whole test is executed for each defined value. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. - * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * run. The whole test is executed for each defined value. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. + * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containerTypeName, - String methodFullName, String precondition, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String methodFullName, String precondition, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { assertNotNull(maximalNumberOfExecutedSetNodesPerRun); for (int j : maximalNumberOfExecutedSetNodesPerRun) { SymbolicExecutionEnvironment env = doSETTest(baseDir, - javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, j, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, j, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } } @@ -1778,57 +1803,57 @@ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containe * Executes method doTest * and disposes the created {@link SymbolicExecutionEnvironment}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, - String containerTypeName, String methodFullName, String precondition, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String containerTypeName, String methodFullName, String precondition, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, simplifyConditions); + doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } @@ -1845,47 +1870,47 @@ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, - includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, false, true); + doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, + includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, false, true); if (env != null) { env.dispose(); } @@ -1904,47 +1929,47 @@ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String proofFilePathInBaseDir, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String proofFilePathInBaseDir, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { boolean originalOneStepSimplification = isOneStepSimplificationEnabled(null); SymbolicExecutionEnvironment env; @@ -1955,26 +1980,26 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } // Make sure that the correct taclet options are defined. setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution env = createSymbolicExecutionEnvironment(baseDir, proofFilePathInBaseDir, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, - simplifyConditions); + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, + simplifyConditions); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); return env; } finally { // Restore original options @@ -1995,49 +2020,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String containerTypeName, final String methodFullName, - String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, - boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String javaPathInBaseDir, String containerTypeName, final String methodFullName, + String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, + boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; @@ -2051,23 +2076,23 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = setDefaultTacletOptions(baseDir, javaPathInBaseDir, - containerTypeName, methodFullName); + containerTypeName, methodFullName); setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, precondition, mergeBranchConditions, useOperationContracts, - useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, - aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, precondition, mergeBranchConditions, useOperationContracts, + useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, + aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore original options @@ -2089,49 +2114,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param baseContractName The name of the contract. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseContractName The name of the contract. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; try { @@ -2142,22 +2167,22 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = - setDefaultTacletOptions(javaPathInBaseDir, baseContractName); + setDefaultTacletOptions(javaPathInBaseDir, baseContractName); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, - useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - truthValueEvaluationEnabled, simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, + useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + truthValueEvaluationEnabled, simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore taclet options @@ -2169,67 +2194,72 @@ protected SymbolicExecutionEnvironment doSETTest(Fi * Internal test method */ private void internalDoSETTest(File oracleFile, - SymbolicExecutionEnvironment env, - String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues) + SymbolicExecutionEnvironment env, + String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); + new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); env.getProof().getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); int nodeCount; // Execute auto mode until no more symbolic execution tree nodes are found or no new rules // are applied. do { - // Store the number of nodes before start of the auto mode - nodeCount = env.getProof().countNodes(); - // Run proof - env.getProofControl().startAndWaitForAutoMode(env.getProof()); - // Update symbolic execution tree - env.getBuilder().analyse(); - // Make sure that not to many set nodes are executed - Map executedSetNodesPerGoal = stopCondition.getExectuedSetNodesPerGoal(); - for (Integer value : executedSetNodesPerGoal.values()) { - assertNotNull(value); - assertTrue(value <= maximalNumberOfExecutedSetNodes, - value + " is not less equal to " + maximalNumberOfExecutedSetNodes); + try { + // Store the number of nodes before start of the auto mode + nodeCount = env.getProof().countNodes(); + // Run proof + env.getProofControl().startAndWaitForAutoMode(env.getProof()); + + // Update symbolic execution tree + env.getBuilder().analyse(); + // Make sure that not to many set nodes are executed + Map executedSetNodesPerGoal = stopCondition.getExectuedSetNodesPerGoal(); + for (Integer value : executedSetNodesPerGoal.values()) { + assertNotNull(value); + assertTrue(value <= maximalNumberOfExecutedSetNodes, + value + " is not less equal to " + maximalNumberOfExecutedSetNodes); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); } } while (stopCondition.wasSetNodeExecuted() && nodeCount != env.getProof().countNodes()); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); } /** * Ensures that the default taclet options are defined. * * @param javaPathInBaseDir The path in the base directory to the java file. - * @param baseContractName The name of the contract to prove. + * @param baseContractName The name of the contract to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(String javaPathInBaseDir, - String baseContractName) + String baseContractName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, - baseContractName, - false, false, false, - false, false, false, - false, false, false, - false, false); + createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, + baseContractName, + false, false, false, + false, false, false, + false, false, false, + false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2238,26 +2268,26 @@ public static Map setDefaultTacletOptions(String javaPathInBaseD /** * Ensures that the default taclet options are defined. * - * @param baseDir The base directory which contains the java file. + * @param baseDir The base directory which contains the java file. * @param javaPathInBaseDir The path in the base directory to the java file. * @param containerTypeName name of the type where the method is implemented/declared - * @param methodFullName The method to prove. + * @param methodFullName The method to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(File baseDir, - String javaPathInBaseDir, - String containerTypeName, - String methodFullName) + String javaPathInBaseDir, + String containerTypeName, + String methodFullName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, - null, false, false, false, - false, false, false, false, - false, false, false); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, + null, false, false, false, + false, false, false, false, + false, false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2266,19 +2296,19 @@ public static Map setDefaultTacletOptions(File baseDir, /** * Ensures that the default taclet options are defined. * - * @param javaFile The java file to load. + * @param javaFile The java file to load. * @param containerTypeName The type name which provides the target. - * @param targetName The target to proof. + * @param targetName The target to proof. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ @SuppressWarnings("unused") public static Map setDefaultTacletOptionsForTarget(File javaFile, - String containerTypeName, final String targetName) + String containerTypeName, final String targetName) throws ProblemLoaderException, ProofInputException { return HelperClassForTests.setDefaultTacletOptionsForTarget(javaFile, containerTypeName, - targetName); + targetName); } /** @@ -2312,14 +2342,14 @@ public static void restoreTacletOptions(Map options) { protected ITermProgramVariableCollectorFactory createNewProgramVariableCollectorFactory( final SymbolicExecutionBreakpointStopCondition breakpointParentStopCondition) { return services -> new TermProgramVariableCollectorKeepUpdatesForBreakpointconditions( - services, breakpointParentStopCondition); + services, breakpointParentStopCondition); } /** * Makes sure that two {@link Term}s are equal. * * @param expected The expected {@link Term}. - * @param actual The actual {@link Term}. + * @param actual The actual {@link Term}. */ protected void assertTerm(Term expected, Term actual) { if (expected != null) { @@ -2339,7 +2369,7 @@ protected void assertTerm(Term expected, Term actual) { * Checks if one-step simplification is enabled in the given {@link Proof}. * * @param proof The {@link Proof} to read from or {@code null} to return the general settings - * value. + * value. * @return {@code true} one step simplification is enabled, {@code false} if disabled. */ public static boolean isOneStepSimplificationEnabled(Proof proof) { @@ -2349,9 +2379,9 @@ public static boolean isOneStepSimplificationEnabled(Proof proof) { /** * Defines if one-step simplification is enabled in general and within the {@link Proof}. * - * @param proof The optional {@link Proof}. + * @param proof The optional {@link Proof}. * @param enabled {@code true} use one-step simplification, {@code false} do not use one-step - * simplification. + * simplification. */ public static void setOneStepSimplificationEnabled(Proof proof, boolean enabled) { HelperClassForTests.setOneStepSimplificationEnabled(proof, enabled); diff --git a/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java b/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java deleted file mode 100644 index 3be1d2528d8..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/Identifiable.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.uka.ilkd.key; - -/** - * @author Alexander Weigl - * @version 1 (14.10.23) - */ -public interface Identifiable { - default String identification() { - return getClass().getName() + "_" + hashCode(); - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java index 0d3fd45622c..29a34424d09 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java @@ -550,19 +550,12 @@ protected void fireAutoModeStopped(ProofEvent e) { } } - /** - * {@inheritDoc} - */ - @Override - public void startAutoMode(Proof proof) { - startAutoMode(proof, proof.openEnabledGoals()); - } /** * {@inheritDoc} */ @Override - public void startAndWaitForAutoMode(Proof proof) { + public void startAndWaitForAutoMode(Proof proof) throws InterruptedException { startAutoMode(proof); waitWhileAutoMode(); } @@ -571,7 +564,7 @@ public void startAndWaitForAutoMode(Proof proof) { * {@inheritDoc} */ @Override - public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) { + public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException { startAutoMode(proof, goals); waitWhileAutoMode(); } @@ -580,7 +573,7 @@ public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) { * {@inheritDoc} */ @Override - public void stopAndWaitAutoMode() { + public void stopAndWaitAutoMode() throws InterruptedException { stopAutoMode(); waitWhileAutoMode(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java index df59e0c1ae7..48dda5aa1f3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java @@ -16,9 +16,11 @@ import de.uka.ilkd.key.prover.impl.ApplyStrategy; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; import de.uka.ilkd.key.util.ProofStarter; - import org.key_project.util.collection.ImmutableList; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + /** * The default implementation of {@link ProofControl}. * @@ -35,15 +37,20 @@ public class DefaultProofControl extends AbstractProofControl { */ private Thread autoModeThread; + /** + * A condition which is non-null during auto-mode. You can wait for end of macro/auto on it. + */ + private Condition inAutoMode; + /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. + * to all started {@link ApplyStrategy} instances. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener) { + DefaultUserInterfaceControl defaultProverTaskListener) { super(defaultProverTaskListener); this.ui = ui; } @@ -51,21 +58,21 @@ public DefaultProofControl(UserInterfaceControl ui, /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * to all started {@link ApplyStrategy} instances. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener, - RuleCompletionHandler ruleCompletionHandler) { + DefaultUserInterfaceControl defaultProverTaskListener, + RuleCompletionHandler ruleCompletionHandler) { super(defaultProverTaskListener, ruleCompletionHandler); this.ui = ui; } @Override public synchronized void startAutoMode(Proof proof, ImmutableList goals, - ProverTaskListener ptl) { + ProverTaskListener ptl) { if (!isInAutoMode()) { autoModeThread = new AutoModeThread(proof, goals, ptl); autoModeThread.start(); @@ -79,19 +86,17 @@ public synchronized void stopAutoMode() { } } + @Override - public void waitWhileAutoMode() { - while (isInAutoMode()) { // Wait until auto mode has stopped. - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } + public void waitWhileAutoMode() throws InterruptedException { + if (inAutoMode != null) { + inAutoMode.await(); } } @Override public boolean isInAutoMode() { - return autoModeThread != null; + return inAutoMode != null; } private class AutoModeThread extends Thread { @@ -105,6 +110,9 @@ public AutoModeThread(Proof proof, ImmutableList goals, ProverTaskListener this.proof = proof; this.goals = goals; this.ptl = ptl; + + var lock = new ReentrantLock(); + inAutoMode = lock.newCondition(); } @Override @@ -113,7 +121,7 @@ public void run() { fireAutoModeStarted(new ProofEvent(proof)); ProofStarter starter = ptl != null ? new ProofStarter( - new CompositePTListener(getDefaultProverTaskListener(), ptl), false) + new CompositePTListener(getDefaultProverTaskListener(), ptl), false) : new ProofStarter(getDefaultProverTaskListener(), false); starter.init(proof); if (goals != null) { @@ -122,6 +130,8 @@ public void run() { starter.start(); } } finally { + inAutoMode.signalAll(); + inAutoMode = null; autoModeThread = null; fireAutoModeStopped(new ProofEvent(proof)); } @@ -150,6 +160,9 @@ public MacroThread(Node node, ProofMacro macro, PosInOccurrence posInOcc) { this.node = node; this.macro = macro; this.posInOcc = posInOcc; + + var lock = new ReentrantLock(); + inAutoMode = lock.newCondition(); } @Override @@ -172,7 +185,9 @@ public void run() { if (ptl != null) { ptl.taskFinished(info); } + inAutoMode.signalAll(); autoModeThread = null; + inAutoMode = null; fireAutoModeStopped(new ProofEvent(proof)); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java index 77b71eaf5df..f30b7bb97d1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java @@ -123,7 +123,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * * @param proof The {@link Proof} to start auto mode of. */ - void startAutoMode(Proof proof); + default void startAutoMode(Proof proof) { startAutoMode(proof, proof.openEnabledGoals());} /** * Starts the auto mode for the given {@link Proof} and the given {@link Goal}s. @@ -143,13 +143,13 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * Stops the currently running auto mode and blocks the current {@link Thread} until auto mode * has stopped. */ - void stopAndWaitAutoMode(); + void stopAndWaitAutoMode() throws InterruptedException; /** * Blocks the current {@link Thread} while the auto mode of this {@link UserInterfaceControl} is * active. */ - void waitWhileAutoMode(); + void waitWhileAutoMode() throws InterruptedException; /** * Starts the auto mode for the given proof which must be contained in this user interface and @@ -158,7 +158,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * @param proof The {@link Proof} to start auto mode and to wait for. * @param goals The {@link Goal}s to close. */ - void startAndWaitForAutoMode(Proof proof, ImmutableList goals); + void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException; /** * Starts the auto mode for the given proof which must be contained in this user interface and @@ -166,7 +166,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * * @param proof The {@link Proof} to start auto mode and to wait for. */ - void startAndWaitForAutoMode(Proof proof); + void startAndWaitForAutoMode(Proof proof) throws InterruptedException; void startFocussedAutoMode(PosInOccurrence focus, Goal goal); diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java index 962228f3ca8..ebe8d366f00 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.macros; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java index 2844075269b..d024e192f97 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroListener.java @@ -35,7 +35,7 @@ public void taskStarted(TaskStartedInfo info) { numOfInvokedMacros++; if (superordinateListener != null) { superordinateListener.taskStarted(new DefaultTaskStartedInfo(TaskKind.Macro, - macroName + (macroName.length() == 0 ? "" : " -- ") + info.message(), + macroName + (macroName.isEmpty() ? "" : " -- ") + info.message(), info.size())); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 533828bb803..06da529607f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -23,13 +23,15 @@ import de.uka.ilkd.key.rule.RuleApp; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.util.Pair; - import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.collection.ImmutableSet; import org.key_project.util.lookup.Lookup; +import java.util.*; +import java.util.stream.Stream; + import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -49,10 +51,14 @@ public class Node implements Iterable { private static final String NODES = "nodes"; - /** the proof the node belongs to */ + /** + * the proof the node belongs to + */ private final Proof proof; - /** The parent node. **/ + /** + * The parent node. + **/ private Node parent = null; /** * The branch location of this proof node. @@ -81,7 +87,9 @@ public class Node implements Iterable { private boolean closed = false; - /** contains non-logical content, used for user feedback */ + /** + * contains non-logical content, used for user feedback + */ private NodeInfo nodeInfo; /** @@ -119,7 +127,7 @@ public class Node implements Iterable { * taclet with an addrule section on this node, then these taclets are stored in this list */ private ImmutableSet localIntroducedRules = - DefaultImmutableSet.nil(); + DefaultImmutableSet.nil(); /** * Holds the undo methods for the information added by rules to the {@code Goal.strategyInfos}. @@ -162,7 +170,9 @@ public void setSequent(Sequent seq) { this.seq = seq; } - /** returns the sequent of this node */ + /** + * returns the sequent of this node + */ public Sequent sequent() { return seq; } @@ -176,7 +186,9 @@ public NodeInfo getNodeInfo() { return nodeInfo; } - /** returns the proof the Node belongs to */ + /** + * returns the proof the Node belongs to + */ public Proof proof() { return proof; } @@ -225,14 +237,16 @@ public RuleApp getAppliedRuleApp() { return appliedRuleApp; } - /** Returns the set of NoPosTacletApps at this node */ + /** + * Returns the set of NoPosTacletApps at this node + */ public Iterable getLocalIntroducedRules() { return localIntroducedRules; } /** * Returns the set of created program variables known in this node. - * + *

    * In the resulting list, the newest additions come first. * * @returns a non-null immutable list of program variables. @@ -249,7 +263,7 @@ public void addLocalProgVars(Iterable elements) { /** * Returns the set of freshly created function symbols known to this node. - * + *

    * In the resulting list, the newest additions come first. * * @return a non-null immutable list of function symbols. @@ -444,7 +458,7 @@ List getLeaves() { /** * @return an iterator for the leaves of the subtree below this node. The computation is called - * at every call! + * at every call! */ public Iterator leavesIterator() { return new NodeIterator(getLeaves().iterator()); @@ -471,13 +485,14 @@ public Iterator subtreeIterator() { return new SubtreeIterator(this); } - /** @return number of children */ + /** + * @return number of children + */ public int childrenCount() { return children.size(); } /** - * * @param i an index (starting at 0). * @return the i-th child of this node. */ @@ -488,7 +503,7 @@ public Node child(int i) { /** * @param child a child of this node. * @return the number of the node child, if it is a child of this node (starting - * with 0), -1 otherwise + * with 0), -1 otherwise */ public int getChildNr(Node child) { int res = 0; @@ -528,16 +543,16 @@ public StringBuffer getUniqueTacletId() { * Helper for {@link #toString()} * * @param prefix needed to keep track if a line has to be printed - * @param tree the tree representation we want to add this subtree " @param preEnumeration the - * enumeration of the parent without the last number + * @param tree the tree representation we want to add this subtree " @param preEnumeration the + * enumeration of the parent without the last number * @param postNr the last number of the parents enumeration - * @param maxNr the number of nodes at this level - * @param ownNr the place of this node at this level + * @param maxNr the number of nodes at this level + * @param ownNr the place of this node at this level * @return the string representation of this node. */ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumeration, - int postNr, int maxNr, int ownNr) { + int postNr, int maxNr, int ownNr) { Iterator childrenIt = childrenIterator(); // Some constants String frontIndent = (maxNr > 1 ? " " : ""); @@ -588,7 +603,7 @@ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumer while (childrenIt.hasNext()) { childId++; childrenIt.next().toString(prefix, tree, newEnumeration, newPostNr, children.size(), - childId); + childId); } return tree; @@ -645,7 +660,7 @@ public String name() { * this node. * * @return true iff the parent of this node has this node as child and this condition holds also - * for the own children. + * for the own children. */ public boolean sanityCheckDoubleLinks() { if (!root()) { @@ -667,7 +682,9 @@ public boolean sanityCheckDoubleLinks() { return true; } - /** marks a node as closed */ + /** + * marks a node as closed + */ Node close() { closed = true; Node tmp = parent; @@ -684,7 +701,7 @@ Node close() { /** * Opens a previously closed node and all its closed parents. *

    - * + *

    * This is, for instance, needed for the {@link MergeRule}: In a situation where a merge node * and its associated partners have been closed and the merge node is then pruned away, the * partners have to be reopened again. Otherwise, we have a soundness issue. @@ -699,7 +716,9 @@ void reopen() { clearNameCache(); } - /** @return true iff this inner node is closeable */ + /** + * @return true iff this inner node is closeable + */ private boolean isCloseable() { assert childrenCount() > 0; for (Node child : children) { @@ -768,7 +787,7 @@ public Iterator iterator() { * Retrieves a user-defined data. * * @param service the class for which the data were registered - * @param any class + * @param any class * @return null or the previous data * @see #register(Object, Class) */ @@ -786,7 +805,7 @@ public T lookup(Class service) { /** * Register a user-defined data in this node info. * - * @param obj an object to be registered + * @param obj an object to be registered * @param service the key under it should be registered * @param */ @@ -797,9 +816,9 @@ public void register(T obj, Class service) { /** * Remove a previous registered user-defined data. * - * @param obj registered object + * @param obj registered object * @param service the key under which the data was registered - * @param arbitray object + * @param arbitray object */ public void deregister(T obj, Class service) { if (userData != null) { @@ -837,4 +856,8 @@ public int getStepIndex() { void setStepIndex(int stepIndex) { this.stepIndex = stepIndex; } + + public Stream childrenStream() { + return children.stream(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java index d7ac6c484d0..6b97d88d82d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java @@ -11,7 +11,6 @@ import java.util.function.Predicate; import javax.swing.*; -import de.uka.ilkd.key.Identifiable; import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.*; @@ -28,7 +27,6 @@ import de.uka.ilkd.key.proof.replay.CopyingProofReplayer; import de.uka.ilkd.key.rule.NoPosTacletApp; import de.uka.ilkd.key.rule.OneStepSimplifier; -import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.merge.MergePartner; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.rule.merge.MergeRuleBuiltInRuleApp; @@ -56,7 +54,7 @@ * information, and methods to apply rules. Furthermore, it offers services that deliver the open * goals, namespaces and several other information about the current state of the proof. */ -public class Proof implements Named, Identifiable { +public class Proof implements Named { /** * The time when the {@link Proof} instance was created. @@ -1477,12 +1475,4 @@ public void copyCachedGoals(Proof referencedFrom, Consumer callbackTota } } } - - /** - * {@inheritDoc} - */ - @Override - public String identification() { - return getClass().getName() + "_" + name + "_" + hashCode(); - } } diff --git a/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java b/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java index 57ad2025a7e..abd24dd8d6e 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java +++ b/key.core/src/test/java/de/uka/ilkd/key/proof/io/TestZipProofSaving.java @@ -33,7 +33,7 @@ private void loadZip(Path fileTarget) throws Exception { } private void proveAndSaveZip(Path file, Path fileTarget) - throws ProblemLoaderException, IOException { + throws ProblemLoaderException, InterruptedException { KeYEnvironment env = KeYEnvironment.load(file.toFile()); env.getProofControl().startAndWaitForAutoMode(env.getLoadedProof()); GZipProofSaver proofSaver = diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java index 6f634c192f1..a80815bbe03 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java @@ -3,10 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; -import java.util.ArrayList; -import java.util.List; -import javax.swing.*; - import de.uka.ilkd.key.control.InteractionListener; import de.uka.ilkd.key.core.InterruptListener; import de.uka.ilkd.key.core.KeYMediator; @@ -20,10 +16,15 @@ import de.uka.ilkd.key.prover.ProverTaskListener; import de.uka.ilkd.key.prover.TaskStartedInfo; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + /** * The Class ProofMacroWorker is a swing worker for the application of proof macros. *

    @@ -39,7 +40,7 @@ public class ProofMacroWorker extends SwingWorker * goals under the current pio, selection remains where it was. */ private static final boolean SELECT_GOAL_AFTER_MACRO = - Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); + Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); /** * The {@link Node} to start macro at. @@ -69,22 +70,26 @@ public class ProofMacroWorker extends SwingWorker private Exception exception; private final List interactionListeners = new ArrayList<>(); + private final Condition finish; + /** * Instantiates a new proof macro worker. * - * @param node the {@link Node} to start macro at. - * @param macro the macro, not null + * @param node the {@link Node} to start macro at. + * @param macro the macro, not null * @param mediator the mediator, not null * @param posInOcc the position, possibly null */ public ProofMacroWorker(Node node, ProofMacro macro, KeYMediator mediator, - PosInOccurrence posInOcc) { + PosInOccurrence posInOcc) { assert macro != null; assert mediator != null; this.node = node; this.macro = macro; this.mediator = mediator; this.posInOcc = posInOcc; + + finish = new ReentrantLock().newCondition(); } @Override @@ -93,7 +98,7 @@ protected ProofMacroFinishedInfo doInBackground() { Proof selectedProof = node.proof(); info = ProofMacroFinishedInfo.getDefaultInfo(macro, selectedProof); ptl.taskStarted( - new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); + new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); try { synchronized (macro) { info = macro.applyTo(mediator.getUI(), node, posInOcc, ptl); @@ -105,6 +110,8 @@ protected ProofMacroFinishedInfo doInBackground() { } catch (final Exception exception) { // This should actually never happen. this.exception = exception; + } finally { + finish.signalAll(); } return info; @@ -120,8 +127,7 @@ protected void done() { synchronized (macro) { mediator.removeInterruptedListener(this); if (!isCancelled() && exception != null) { // user cancelled task is fine, we do not - // report this - // This should actually never happen. + // report this // This should actually never happen. LOGGER.error("", exception); IssueDialog.showExceptionDialog(MainWindow.getInstance(), exception); } @@ -138,7 +144,7 @@ protected void done() { } protected void emitProofMacroFinished(Node node, ProofMacro macro, PosInOccurrence posInOcc, - ProofMacroFinishedInfo info) { + ProofMacroFinishedInfo info) { interactionListeners.forEach((l) -> l.runMacro(node, macro, posInOcc, info)); } @@ -167,4 +173,11 @@ private void selectOpenGoalBelow() { } } } + + /** + * @return a condition for waiting on this thread to be finished + */ + public Condition getFinish() { + return finish; + } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java index 6c94d762e00..90c9398b076 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofScriptWorker.java @@ -183,6 +183,13 @@ public void done() { } mediator.removeInterruptedListener(this); + runWithDeadline(() -> mediator.startInterface(true), 1000); + runWithDeadline(() -> { + try { + mediator.getUI().getProofControl().stopAndWaitAutoMode(); + } catch (InterruptedException ignored) { + } + }, 1000); final Proof proof = initiallySelectedGoal != null ? initiallySelectedGoal.proof() : mediator.getSelectedProof(); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java index ceaba6d1bb1..2b8a53215d5 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java @@ -24,6 +24,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.awt.event.ActionEvent; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + /** * This class provides an action for KeY UI which runs a set of specified proof files automatically. * The intent of this class is to have a massive test feature for the quality assurance of the KeY @@ -73,7 +83,7 @@ public class RunAllProofsAction extends MainWindowAction { @NonNull private List loadFiles() throws IOException { LOGGER.info("Use 'export {}=<...>' to set the input file for {}.", ENV_VARIABLE, - getClass().getSimpleName()); + getClass().getSimpleName()); InputStream stream; if (RUN_ALL_PROOFS_UI == null) { @@ -87,7 +97,7 @@ private List loadFiles() throws IOException { } try (BufferedReader in = - new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { return in.lines().filter(it -> !it.startsWith("#") && !it.trim().isEmpty()) .map(it -> (it.startsWith("/") ? new File(it) : new File(exampleDir, it)) .getAbsoluteFile()) @@ -110,13 +120,13 @@ public RunAllProofsAction(MainWindow mainWindow) { setName("Run all proofs"); setTooltip( - "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); + "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); } @Override public void actionPerformed(ActionEvent e) { - WindowUserInterfaceControl ui = mainWindow.getUserInterface(); + WindowUserInterfaceControl ui = mainWindow.getUserInterface(); for (int i = 0; i < files.size(); i++) { LOGGER.info("{}: {}\n", i, files.get(i)); } @@ -126,7 +136,7 @@ public void actionPerformed(ActionEvent e) { ui.reportStatus(this, "Run: " + absFile); LOGGER.info("Run: {}", absFile); ProblemLoader problemLoader = - ui.getProblemLoader(absFile, null, null, null, getMediator()); + ui.getProblemLoader(absFile, null, null, null, getMediator()); problemLoader.runSynchronously(); LOGGER.info("Loaded: {}", absFile); @@ -135,7 +145,10 @@ public void actionPerformed(ActionEvent e) { MediatorProofControl control = ui.getProofControl(); if (control.isAutoModeSupported(proof)) { control.startAutoMode(proof, proof.openEnabledGoals()); - control.waitWhileAutoMode(); + try { + control.waitWhileAutoMode(); + } catch (InterruptedException ignored) { + } } LOGGER.info("Finish: ({}) {}", getMediator().getSelectedProof().closed(), absFile); getMediator().getSelectedProof().dispose(); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java b/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java index 89c4cb0d06b..50c05be74fa 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/ui/ConsoleUserInterfaceControl.java @@ -172,7 +172,11 @@ public void taskFinished(TaskFinishedInfo info) { } else if (macroChosen()) { applyMacro(); } else { - finish(proof); + try { + finish(proof); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } @@ -228,7 +232,7 @@ public void registerProofAggregate(ProofAggregate pa) { proofStack = proofStack.prepend(pa.getFirstProof()); } - void finish(Proof proof) { + void finish(Proof proof) throws InterruptedException { // setInteractive(false) has to be called because the ruleAppIndex // has to be notified that we work in auto mode (CS) mediator.setInteractive(false); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java b/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java index 54009075944..839de98f341 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/ui/MediatorProofControl.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import javax.swing.*; @@ -45,6 +47,8 @@ public class MediatorProofControl extends AbstractProofControl { private final AbstractMediatorUserInterfaceControl ui; private AutoModeWorker worker; + private Condition inAutoMode; + public MediatorProofControl(AbstractMediatorUserInterfaceControl ui) { super(ui, ui); this.ui = ui; @@ -101,17 +105,14 @@ public void stopAutoMode() { * {@inheritDoc} */ @Override - public void waitWhileAutoMode() { + public void waitWhileAutoMode() throws InterruptedException { if (SwingUtilities.isEventDispatchThread()) { LOGGER.error("", new IllegalStateException( "tried to block the UI thread whilst waiting for auto mode to finish")); return; // do not block the UI thread } - while (ui.getMediator().isInAutoMode()) { // Wait until auto mode has stopped. - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } + if (inAutoMode != null) { + inAutoMode.await(); } } @@ -138,6 +139,7 @@ public boolean isAutoModeSupported(Proof proof) { public void runMacro(Node node, ProofMacro macro, PosInOccurrence posInOcc) { KeYMediator mediator = ui.getMediator(); final ProofMacroWorker worker = new ProofMacroWorker(node, macro, mediator, posInOcc); + inAutoMode = worker.getFinish(); interactionListeners.forEach(worker::addInteractionListener); mediator.initiateAutoMode(node.proof(), true, false); mediator.addInterruptedListener(worker); @@ -174,6 +176,9 @@ public AutoModeWorker(final Proof proof, final ImmutableList goals, if (ui.getMediator().getAutoSaver() != null) { applyStrategy.addProverTaskObserver(ui.getMediator().getAutoSaver()); } + + var lock = new ReentrantLock(); + inAutoMode = lock.newCondition(); } @Override @@ -185,6 +190,9 @@ protected void done() { } catch (final CancellationException exception) { // when the user canceled it's not an error } finally { + // release threads waiting on automode finish + inAutoMode.signalAll(); + // make it possible to free memory and falsify the isAutoMode() property worker = null; // Clear strategy @@ -212,7 +220,7 @@ private void notifyException(final Throwable exception) { } @Override - protected ApplyStrategyInfo doInBackground() throws Exception { + protected ApplyStrategyInfo doInBackground() { boolean stopMode = proof.getSettings().getStrategySettings().getActiveStrategyProperties() .getProperty(StrategyProperties.STOPMODE_OPTIONS_KEY) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index 248210a9f7f..fd1b8352356 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -1,27 +1,75 @@ package org.keyproject.key.api; +import de.uka.ilkd.key.control.AbstractUserInterfaceControl; +import de.uka.ilkd.key.control.DefaultUserInterfaceControl; import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.gui.Example; import de.uka.ilkd.key.gui.ExampleChooser; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.ProofMacroFacade; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; +import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; import de.uka.ilkd.key.macros.scripts.ProofScriptCommandFacade; -import de.uka.ilkd.key.proof.Node; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.Statistics; +import de.uka.ilkd.key.macros.scripts.ProofScriptEngine; +import de.uka.ilkd.key.macros.scripts.ScriptException; +import de.uka.ilkd.key.parser.Location; +import de.uka.ilkd.key.pp.IdentitySequentPrintFilter; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.pp.NotationInfo; +import de.uka.ilkd.key.pp.PosTableLayouter; +import de.uka.ilkd.key.proof.*; +import de.uka.ilkd.key.proof.init.*; +import de.uka.ilkd.key.proof.io.AbstractProblemLoader; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import de.uka.ilkd.key.prover.ProverTaskListener; +import de.uka.ilkd.key.prover.TaskFinishedInfo; +import de.uka.ilkd.key.prover.TaskStartedInfo; +import de.uka.ilkd.key.speclang.PositionedString; import de.uka.ilkd.key.util.KeYConstants; import org.eclipse.lsp4j.jsonrpc.CompletableFutures; +import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.keyproject.key.api.adapters.KeyAdapter; +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSet; import org.keyproject.key.api.data.*; +import org.keyproject.key.api.data.KeyIdentifications.*; +import org.keyproject.key.api.internal.NodeText; import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteapi.PrintOptions; +import org.keyproject.key.api.remoteclient.ClientApi; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.concurrent.CompletableFuture; - -public record KeyApiImpl(KeyAdapter adapter) implements KeyApi { +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + +public final class KeyApiImpl implements KeyApi { + private final KeyIdentifications data = new KeyIdentifications(); + + private ClientApi clientApi; + private final ProverTaskListener clientListener = new ProverTaskListener() { + @Override + public void taskStarted(TaskStartedInfo info) { + clientApi.taskStarted(info); + } + + @Override + public void taskProgress(int position) { + clientApi.taskProgress(position); + } + + @Override + public void taskFinished(TaskFinishedInfo info) { + clientApi.taskFinished(info); + } + }; + private final AtomicInteger uniqueCounter = new AtomicInteger(); + + public KeyApiImpl() { + } @Override @JsonRequest @@ -49,120 +97,461 @@ public CompletableFuture getVersion() { } @Override - public CompletableFuture> getAvailableMacros() { + public CompletableFuture> getAvailableMacros() { return CompletableFuture.completedFuture( - ProofMacroFacade.instance().getMacros().stream().toList() + ProofMacroFacade.instance().getMacros().stream() + .map(ProofMacroDesc::from).toList() ); } @Override - public CompletableFuture>> getAvailableScriptCommands() { + public CompletableFuture> getAvailableScriptCommands() { return CompletableFuture.completedFuture( - ProofScriptCommandFacade.instance().getScriptCommands().stream().toList()); + ProofScriptCommandFacade.instance().getScriptCommands().stream().map(ProofScriptCommandDesc::from).toList()); } @Override - public CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options) { - return null; + public CompletableFuture script(ProofId proofId, String scriptLine, StreategyOptions options) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + var env = data.find(proofId.env()); + var pe = new ProofScriptEngine(scriptLine, Location.UNDEFINED); + + try { + pe.execute((AbstractUserInterfaceControl) env.getProofControl(), proof); + return null; + } catch (IOException | InterruptedException | ScriptException e) { + throw new RuntimeException(e); + } + }); } @Override - public CompletableFuture macro(Proof id, String macroId, StreategyOptions options) { - return null; + public CompletableFuture macro(ProofId proofId, String macroId, StreategyOptions options) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + var env = data.find(proofId.env()); + var macro = Objects.requireNonNull(ProofMacroFacade.instance().getMacro(macroId)); + + try { + var info = macro.applyTo(env.getUi(), proof, proof.openGoals(), null, clientListener); + return MacroStatistic.from(proofId, info); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } @Override - public CompletableFuture auto(Proof id, StreategyOptions options) { - return null; + public CompletableFuture auto(ProofId proofId, StreategyOptions options) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + var env = data.find(proofId.env()); + try { + env.getProofControl().startAndWaitForAutoMode(proof); + //clientListener); + return null;//MacroStatistic.from(proofId, info); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } @Override - public CompletableFuture dispose(Proof id) { - return null; + public CompletableFuture dispose(ProofId id) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(id); + data.dispose(id); + proof.dispose(); + return true; + }); } @Override - public CompletableFuture goals(Proof id) { - return null; + public CompletableFuture> goals(ProofId proofId, boolean onlyOpened, boolean onlyEnabled) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + if (onlyOpened && !onlyEnabled) { + return asNodeDesc(proofId, proof.openGoals()); + } else if (onlyEnabled && onlyOpened) { + return asNodeDesc(proofId, proof.openEnabledGoals()); + } else { + return asNodeDesc(proofId, proof.allGoals()); + } + }); + } + + private List asNodeDesc(ProofId proofId, ImmutableList goals) { + return asNodeDesc(proofId, goals.stream().map(Goal::node)); + } + + private List asNodeDesc(ProofId proofId, Stream nodes) { + return nodes.map(it -> asNodeDesc(proofId, it)).toList(); + } + + private NodeDesc asNodeDesc(ProofId proofId, Node it) { + return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), it.getNodeInfo().getScriptRuleApplication()); } @Override - public CompletableFuture tree(Proof proof) { - return null; + public CompletableFuture tree(ProofId proofId) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + return asNodeDescRecursive(proofId, proof.root()); + }); + } + + private NodeDesc asNodeDescRecursive(ProofId proofId, Node root) { + return new NodeDesc(new NodeId(proofId, root.serialNr()), + root.getNodeInfo().getBranchLabel(), + root.getNodeInfo().getScriptRuleApplication(), + root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList() + ); } @Override - public CompletableFuture root(Proof proof) { - return null; + public CompletableFuture root(ProofId proofId) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + return asNodeDesc(proofId, proof.root()); + }); } @Override - public CompletableFuture> children(Proof proof, Node nodeId) { - return null; + public CompletableFuture> children(NodeId nodeId) { + return CompletableFuture.supplyAsync(() -> { + var node = data.find(nodeId); + return asNodeDesc(nodeId.proofId(), node.childrenStream()); + }); } @Override - public CompletableFuture> pruneTo(Proof proof, Node nodeId) { + public CompletableFuture> pruneTo(NodeId nodeId) { return null; } @Override - public CompletableFuture statistics(Proof proof) { - return null; + public CompletableFuture statistics(ProofId proofId) { + return CompletableFuture.supplyAsync(() -> { + var proof = data.find(proofId); + return proof.getStatistics(); + }); } @Override - public CompletableFuture treeRoot(Proof proof) { + public CompletableFuture treeRoot(ProofId proof) { return null; } @Override - public CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId) { + public CompletableFuture> treeChildren(ProofId proof, TreeNodeId nodeId) { return null; } @Override - public CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId) { + public CompletableFuture> treeSubtree(ProofId proof, TreeNodeId nodeId) { return null; } @Override - public CompletableFuture> sorts(KeYEnvironment env) { - return null; + public CompletableFuture> sorts(EnvironmentId envId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(envId); + var sorts = env.getServices().getNamespaces().sorts().allElements(); + return sorts.stream().map(SortDesc::from).toList(); + }); } @Override - public CompletableFuture> functions(KeYEnvironment env) { - return null; + public CompletableFuture> functions(EnvironmentId envId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(envId); + var functions = env.getServices().getNamespaces().functions().allElements(); + return functions.stream().map(FunctionDesc::from).toList(); + }); } @Override - public CompletableFuture> contracts(KeYEnvironment env) { - return null; + public CompletableFuture> contracts(EnvironmentId envId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(envId); + var contracts = env.getAvailableContracts(); + return contracts.stream().map(it -> ContractDesc.from(envId, env.getServices(), it)).toList(); + }); } @Override - public CompletableFuture openContract(KeYEnvironment env, String contractId) { - return null; + public CompletableFuture openContract(ContractId contractId) { + return CompletableFuture.supplyAsync(() -> { + var env = data.find(contractId.envId()); + var contracts = env.getAvailableContracts(); + var contract = contracts.stream().filter(it -> it.id() == contractId.contractId()).findFirst(); + if (contract.isPresent()) { + try { + var proof = env.createProof(contract.get().createProofObl(env.getInitConfig())); + return data.register(contractId.envId(), proof); + } catch (ProofInputException e) { + throw new RuntimeException(e); + } + } else { + return null; + } + }); } @Override - public CompletableFuture print(Node id) { - return null; + public CompletableFuture print(NodeId nodeId, PrintOptions options) { + return CompletableFuture.supplyAsync(() -> { + var node = data.find(nodeId); + var env = data.find(nodeId.proofId().env()); + var notInfo = new NotationInfo(); + final var layouter = new PosTableLayouter(options.width(), options.indentation(), options.pure()); + var lp = new LogicPrinter(notInfo, env.getServices(), layouter); + lp.printSequent(node.sequent()); + + var id = new NodeTextId(nodeId, uniqueCounter.getAndIncrement()); + var t = new NodeText(lp.result(), layouter.getInitialPositionTable()); + data.register(id, t); + return new NodeTextDesc(id, lp.result()); + }); } + private final IdentitySequentPrintFilter filter = new IdentitySequentPrintFilter(); + @Override - public CompletableFuture> actions(PrintId id, int pos) { - return null; + public CompletableFuture> actions(NodeTextId printId, int pos) { + return CompletableFuture.supplyAsync(() -> { + var node = data.find(printId.nodeId()); + var proof = data.find(printId.nodeId().proofId()); + var goal = proof.getOpenGoal(node); + var nodeText = data.find(printId); + var pis = nodeText.table().getPosInSequent(pos, filter); + return new TermActionUtil(printId, data.find(printId.nodeId().proofId().env()), pis, goal) + .getActions(); + }); + } @Override - public CompletableFuture> applyAction(TermActionId id) { + public CompletableFuture> applyAction(TermActionId id) { return null; } @Override - public void freePrint(PrintId id) { + public void freePrint(NodeTextId printId) { + CompletableFuture.runAsync(() -> data.dispose(printId)); + } + + public void setClientApi(ClientApi remoteProxy) { + clientApi = remoteProxy; + } + + private final DefaultUserInterfaceControl control = new MyDefaultUserInterfaceControl(); + + @Override + public CompletableFuture loadExample(String id) { + return CompletableFutures.computeAsync((c) -> { + var examples = ExampleChooser.listExamples(ExampleChooser.lookForExamples()) + .stream().filter(it -> it.getName().equals(id)).findFirst(); + if (examples.isPresent()) { + var ex = examples.get(); + Proof proof = null; + KeYEnvironment env = null; + try { + var loader = control.load(JavaProfile.getDefaultProfile(), + ex.getObligationFile(), null, null, null, null, true, null); + InitConfig initConfig = loader.getInitConfig(); + + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + proof = Objects.requireNonNull(env.getLoadedProof()); + var proofId = new ProofId(envId, proof.name().toString()); + return data.register(proofId, proof); + } catch (ProblemLoaderException e) { + if (proof != null) proof.dispose(); + if (env != null) env.dispose(); + throw new RuntimeException(e); + } + } + throw new IllegalArgumentException("Unknown example"); + }); + } + + @Override + public CompletableFuture loadProblem(ProblemDefinition problem) { + return CompletableFutures.computeAsync((c) -> { + Proof proof = null; + KeYEnvironment env = null; + /* var loader = control.load(JavaProfile.getDefaultProfile(), + ex.getObligationFile(), null, null, null, null, true, null); + InitConfig initConfig = loader.getInitConfig(); + + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + proof = Objects.requireNonNull(env.getLoadedProof()); + var proofId = new ProofId(envId, proof.name().toString()); + return data.register(proofId, proof);*/ + return null; + }); } + + @Override + public CompletableFuture loadKey(String content) { + return CompletableFutures.computeAsync((c) -> { + Proof proof = null; + KeYEnvironment env = null; + try { + final var tempFile = File.createTempFile("json-rpc-", ".key"); + Files.writeString(tempFile.toPath(), content); + var loader = control.load(JavaProfile.getDefaultProfile(), + tempFile, null, null, null, null, true, null); + InitConfig initConfig = loader.getInitConfig(); + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + proof = Objects.requireNonNull(env.getLoadedProof()); + var proofId = new ProofId(envId, proof.name().toString()); + return data.register(proofId, proof); + } catch (ProblemLoaderException | IOException e) { + if (proof != null) proof.dispose(); + if (env != null) env.dispose(); + throw new RuntimeException(e); + } + }); + } + + @Override + public CompletableFuture loadTerm(String term) { + return loadKey("\\problem{ " + term + " }"); + } + + @Override + public CompletableFuture> load(LoadParams params) { + return CompletableFutures.computeAsync((c) -> { + Proof proof = null; + KeYEnvironment env = null; + try { + var loader = control.load(JavaProfile.getDefaultProfile(), + params.keyFile(), + params.classPath(), + params.bootClassPath(), + params.includes(), + null, + true, + null); + InitConfig initConfig = loader.getInitConfig(); + env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + loader.getProofScript(), loader.getResult()); + var envId = new EnvironmentId(env.toString()); + data.register(envId, env); + if ((proof = env.getLoadedProof()) != null) { + var proofId = new ProofId(envId, proof.name().toString()); + return Either.forRight(data.register(proofId, proof)); + } else { + return Either.forLeft(envId); + } + } catch (ProblemLoaderException e) { + if (proof != null) proof.dispose(); + if (env != null) env.dispose(); + throw new RuntimeException(e); + } + }); + } + + private class MyDefaultUserInterfaceControl extends DefaultUserInterfaceControl { + @Override + public void taskStarted(TaskStartedInfo info) { + clientApi.taskStarted(info); + } + + @Override + public void taskProgress(int position) { + clientApi.taskProgress(position); + } + + @Override + public void taskFinished(TaskFinishedInfo info) { + clientApi.taskFinished(info); + } + + @Override + protected void macroStarted(TaskStartedInfo info) { + clientApi.taskStarted(info); + } + + @Override + protected synchronized void macroFinished(ProofMacroFinishedInfo info) { + clientApi.taskFinished(info); + } + + @Override + public void loadingStarted(AbstractProblemLoader loader) { + super.loadingStarted(loader); + } + + @Override + public void loadingFinished(AbstractProblemLoader loader, IPersistablePO.LoadedPOContainer poContainer, ProofAggregate proofList, AbstractProblemLoader.ReplayResult result) throws ProblemLoaderException { + super.loadingFinished(loader, poContainer, proofList, result); + } + + @Override + public void progressStarted(Object sender) { + super.progressStarted(sender); + } + + @Override + public void progressStopped(Object sender) { + super.progressStopped(sender); + } + + @Override + public void reportStatus(Object sender, String status, int progress) { + super.reportStatus(sender, status, progress); + } + + @Override + public void reportStatus(Object sender, String status) { + super.reportStatus(sender, status); + } + + @Override + public void resetStatus(Object sender) { + super.resetStatus(sender); + } + + @Override + public void reportException(Object sender, ProofOblInput input, Exception e) { + super.reportException(sender, input, e); + } + + @Override + public void setProgress(int progress) { + super.setProgress(progress); + } + + @Override + public void setMaximum(int maximum) { + super.setMaximum(maximum); + } + + @Override + public void reportWarnings(ImmutableSet warnings) { + super.reportWarnings(warnings); + } + + @Override + public void showIssueDialog(Collection issues) { + super.showIssueDialog(issues); + } + } + + } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java new file mode 100644 index 00000000000..0a27c633e5a --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java @@ -0,0 +1,8 @@ +package org.keyproject.key.api; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record NodeTextDesc(NodeTextId id, String result) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java new file mode 100644 index 00000000000..a99bed5fda9 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java @@ -0,0 +1,10 @@ +package org.keyproject.key.api; + +import org.keyproject.key.api.data.KeyIdentifications.NodeId; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record NodeTextId(NodeId nodeId, int nodeTextId) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index 408cc36acdd..b95ae6eebe2 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -115,6 +115,8 @@ public void run() { } try { + final var keyApi = new KeyApiImpl(); + if (websocket) { var launcherBuilder = new WebSocketLauncherBuilder() .setOutput(out) @@ -122,14 +124,18 @@ public void run() { .traceMessages(new PrintWriter(System.err)) .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - launcherBuilder.setLocalService(new KeyApiImpl(adapter)); + launcherBuilder.setLocalService(keyApi); launcherBuilder.setRemoteInterface(ClientApi.class); - launcherBuilder.create().startListening().get(); + + final var clientApiLauncher = launcherBuilder.create(); + keyApi.setClientApi(clientApiLauncher.getRemoteProxy()); + clientApiLauncher.startListening().get(); } else { establishStreams(); try (var lin = in; var lout = out) { - var listener = launch(lout, lin); + var listener = launch(lout, lin, keyApi); LOGGER.info("JSON-RPC is listening for requests"); + keyApi.setClientApi(listener.getRemoteProxy()); listener.startListening().get(); } } @@ -143,7 +149,7 @@ public static void configureJson(GsonBuilder gsonBuilder) { adapter = new KeyAdapter(gsonBuilder); } - public static Launcher launch(OutputStream out, InputStream in) { + public static Launcher launch(OutputStream out, InputStream in, KeyApiImpl keyApi) { // var localServices = getLocalServices(); // var remoteInterfaces = getRemoteInterfaces(); var launcherBuilder = new Launcher.Builder() @@ -154,7 +160,7 @@ public static Launcher launch(OutputStream out, InputStream in) { launcherBuilder.configureGson(StartServer::configureJson); //if (localServices != null && !localServices.isEmpty()) - launcherBuilder.setLocalService(new KeyApiImpl(adapter)); + launcherBuilder.setLocalService(keyApi); //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) launcherBuilder.setRemoteInterface(ClientApi.class); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java new file mode 100644 index 00000000000..51e0053eed6 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -0,0 +1,125 @@ +package org.keyproject.key.api; + +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.control.ProofControl; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.PosInOccurrence; +import de.uka.ilkd.key.macros.ProofMacro; +import de.uka.ilkd.key.macros.ProofMacroFacade; +import de.uka.ilkd.key.pp.PosInSequent; +import de.uka.ilkd.key.proof.Goal; +import de.uka.ilkd.key.rule.*; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSLList; +import org.keyproject.key.api.data.KeyIdentifications; +import org.keyproject.key.api.data.TermActionDesc; +import org.keyproject.key.api.data.TermActionKind; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class TermActionUtil { + private static final Set CLUTTER_RULESETS = + Set.of(new Name("notHumanReadable"), + new Name("obsolete"), + new Name("pullOutQuantifierAll"), + new Name("pullOutQuantifierEx")); + private static final Set CLUTTER_RULES = Set.of( + new Name("cut_direct_r"), + new Name("cut_direct_l"), + new Name("case_distinction_r"), + new Name("case_distinction_l"), + new Name("local_cut"), + new Name("commute_and_2"), + new Name("commute_or_2"), + new Name("boxToDiamond"), + new Name("pullOut"), + new Name("typeStatic"), + new Name("less_is_total"), + new Name("less_zero_is_total"), + new Name("applyEqReverse"), + + // the following are used for drag'n'drop interactions + new Name("eqTermCut"), + new Name("instAll"), + new Name("instEx") + ); + private static final Set FILTER_SCRIPT_COMMANDS = Set.of( + "exit", + "leave", + "javascript", + "skip", + "macro", + "rule", + "script"); + + private final PosInSequent pos; + private final Goal goal; + private final PosInOccurrence occ; + + private final List actions = new ArrayList<>(1024); + private final NodeTextId nodeTextId; + + public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment env, @NonNull PosInSequent pos, @NonNull Goal goal) { + this.pos = pos; + this.goal = goal; + this.nodeTextId = nodeTextId; + occ = pos.getPosInOccurrence(); + ProofControl c = env.getUi().getProofControl(); + final ImmutableList builtInRules = c.getBuiltInRule(goal, occ); + for (ProofMacro macro : ProofMacroFacade.instance().getMacros()) { + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "macro:" + macro.getScriptCommandName()); + TermActionDesc ta = new TermActionDesc(id, macro.getName(), macro.getDescription(), macro.getCategory(), TermActionKind.Macro); + add(ta); + } + ImmutableList findTaclet = c.getFindTaclet(goal, occ); + var find = removeRewrites(findTaclet) + .prepend(c.getRewriteTaclet(goal, occ)); + var nofind = c.getNoFindTaclet(goal); + + + for (TacletApp tacletApp : find) { + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "find:" + tacletApp.rule()); + TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), + tacletApp.rule().toString(), "", TermActionKind.Taclet); + add(ta); + } + + for (TacletApp tacletApp : nofind) { + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "nofind:" + tacletApp.rule()); + TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), + tacletApp.rule().toString(), "", TermActionKind.Taclet); + add(ta); + } + } + + private void add(TermActionDesc ta) { + actions.add(ta); + } + + /** + * Removes RewriteTaclet from the list. + * + * @param list the IList from where the RewriteTaclet are removed + * @return list without RewriteTaclets + */ + private static ImmutableList removeRewrites( + ImmutableList list) { + ImmutableList result = ImmutableSLList.nil(); + for (TacletApp tacletApp : list) { + Taclet taclet = tacletApp.taclet(); + result = (taclet instanceof RewriteTaclet ? result : result.prepend(tacletApp)); + } + return result; + } + + public List getActions() { + return actions; + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 9168a2128f5..68b330491fc 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -1,20 +1,14 @@ package org.keyproject.key.api.adapters; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import de.uka.ilkd.key.Identifiable; import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.macros.ProofMacro; -import de.uka.ilkd.key.macros.ProofMacroFacade; -import de.uka.ilkd.key.proof.Proof; import org.keyproject.key.api.data.MacroDescription; import java.io.File; import java.io.IOException; -import java.lang.ref.WeakReference; import java.lang.reflect.Type; /** @@ -22,40 +16,39 @@ * @version 1 (14.10.23) */ public class KeyAdapter { - private final BiMap> map = HashBiMap.create(1024); + //private final BiMap> map = HashBiMap.create(1024); //private final TypeAdapter adaptor; public KeyAdapter(GsonBuilder gson) { gson.registerTypeAdapter(File.class, new FileTypeAdapter()); - gson.registerTypeAdapter(Function.class, new FunctionTypeAdapter()); - gson.registerTypeAdapter(Proof.class, new IdentifiableTypeAdapter()); - gson.registerTypeAdapter(ProofMacro.class, new MacroTypeAdapter()); - //adaptor = gson.create().getAdapter(Object.class); + //gson.registerTypeAdapter(Function.class, new FunctionSerializer()); + //gson.registerTypeAdapter(ProofMacro.class, new MacroSerializer()); } + /* //translating entities to identification strings - public String insert(Identifiable p) { + public void insert(Identifiable p) { var id = p.identification(); if (!map.containsKey(id)) { map.put(id, new WeakReference<>(p)); } - return id; } public Object find(String id) { return map.get(id).get(); } //endregion + */ - class MacroTypeAdapter implements JsonSerializer { + static class MacroSerializer implements JsonSerializer { @Override public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationContext context) { return context.serialize(MacroDescription.from(src)); } } - class FileTypeAdapter extends TypeAdapter { + static class FileTypeAdapter extends TypeAdapter { @Override public void write(JsonWriter out, File value) throws IOException { out.value(value.toString()); @@ -67,7 +60,7 @@ public File read(JsonReader in) throws IOException { } } - class FunctionTypeAdapter implements JsonSerializer { + static class FunctionSerializer implements JsonSerializer { @Override public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationContext context) { var obj = new JsonObject(); @@ -81,7 +74,7 @@ public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationCont } } - class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { + /*class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { @Override public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return (Identifiable) find(json.getAsString()); @@ -92,5 +85,5 @@ public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerialization insert(src); return context.serialize(src.identification()); } - } + }*/ } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java index a81f8d863db..531bc2fb56d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java @@ -1,8 +1,17 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.speclang.Contract; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record ContractDesc() { +public record ContractDesc(KeyIdentifications.ContractId contractId, String name, String displayName, + String typeName, String htmlText, String plainText) { + public static ContractDesc from(KeyIdentifications.EnvironmentId envId, Services services, Contract it) { + return new ContractDesc(new KeyIdentifications.ContractId(envId, it.id()), + it.getName(), it.getDisplayName(), it.getTypeName(), + it.getHTMLText(services), it.getPlainText(services)); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java index 0c612b44cc2..1868871c0e3 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -1,10 +1,21 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.logic.op.Function; + import java.util.List; /** * @author Alexander Weigl * @version 1 (15.10.23) */ -public record FunctionDesc(String name, String sort, List sorts) { +public record FunctionDesc(String name, String sort, SortDesc retSort, List argSorts, boolean rigid, + boolean unique, boolean skolemConstant) { + public static FunctionDesc from(Function fn) { + return new FunctionDesc(fn.name().toString(), fn.proofToString(), + SortDesc.from(fn.sort()), + fn.argSorts().stream().map(SortDesc::from).toList(), + fn.isRigid(), + fn.isUnique(), + fn.isSkolemConstant()); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java b/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java deleted file mode 100644 index 7a0e2f264e0..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/GoalText.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.keyproject.key.api.data; - -import de.uka.ilkd.key.pp.PositionTable; - -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record GoalText(PrintId id, String text, PositionTable table) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java new file mode 100644 index 00000000000..0698a50a982 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java @@ -0,0 +1,163 @@ +package org.keyproject.key.api.data; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import de.uka.ilkd.key.control.KeYEnvironment; +import de.uka.ilkd.key.proof.Node; +import de.uka.ilkd.key.proof.Proof; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.keyproject.key.api.NodeTextId; +import org.keyproject.key.api.internal.NodeText; + +import java.lang.ref.WeakReference; +import java.util.Objects; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class KeyIdentifications { + private final BiMap mapEnv = HashBiMap.create(16); + + public KeyEnvironmentContainer getContainer(EnvironmentId environmentId) { + return Objects.requireNonNull(mapEnv.get(environmentId), "Could not find environment for id" + environmentId); + } + + public ProofContainer getContainer(ProofId proofId) { + return Objects.requireNonNull(getContainer(proofId.env()).mapProof.get(proofId), + "Could not find proof for id" + proofId); + } + + public KeYEnvironment find(EnvironmentId envid) { + return Objects.requireNonNull(getContainer(envid).env.get(), "Environment was removed by gc"); + } + + @NonNull + public Proof find(ProofId proofId) { + return Objects.requireNonNull(getContainer(proofId).wProof.get(), "Could not find a proof for id " + proofId); + } + + @NonNull + public NodeText find(NodeTextId nodeTextId) { + return Objects.requireNonNull(getContainer(nodeTextId.nodeId().proofId()).mapGoalText.get(nodeTextId), + "Could not find a print-out with the id " + nodeTextId); + } + + public void dispose(NodeTextId nodeTextId) { + var c = getContainer(nodeTextId.nodeId().proofId()); + c.mapGoalText.remove(nodeTextId); + } + + public void dispose(ProofId id) { + var c = getContainer(id); + getContainer(id.env).mapProof.remove(id); + c.dispose(); + } + + public Node find(NodeId nodeId) { + @NonNull Proof p = find(nodeId.proofId); + var opt = p.findAny(it -> it.serialNr() == nodeId.nodeId()); + return Objects.requireNonNull(opt, "Could not find node with serialNr " + nodeId.nodeId); + } + + public ProofId register(EnvironmentId envId, Proof proof) { + var id = new ProofId(envId, proof.name().toString()); + getContainer(envId).mapProof.put(id, new ProofContainer(proof)); + return id; + } + + public void register(NodeTextId nodeId, NodeText nodeText) { + var c = getContainer(nodeId.nodeId().proofId()); + c.mapGoalText().put(nodeId, nodeText); + + } + + public EnvironmentId register(EnvironmentId envId, KeYEnvironment env) { + mapEnv.put(envId, new KeyEnvironmentContainer(env)); + return envId; + } + + public ProofId register(ProofId proofId, Proof proof) { + getContainer(proofId.env()).mapProof.put(proofId, new ProofContainer(proof)); + return proofId; + } + + + /** + * @author Alexander Weigl + * @version 1 (28.10.23) + */ + public record EnvironmentId(String envId) { + } + + /** + * @author Alexander Weigl + * @version 1 (28.10.23) + */ + public record ContractId(EnvironmentId envId, int contractId) { + } + + /** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ + public record NodeId(ProofId proofId, int nodeId) { + } + + public record ProofId(EnvironmentId env, String proofId) { + } + + /** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ + public record PrintId(String id) { + } + + /** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ + public record TermActionId(NodeId nodeId, String pio, String id) { + } + + /** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ + public record TreeNodeId(String id) { + } + + + /** + * @author Alexander Weigl + * @version 1 (28.10.23) + */ + public record KeyEnvironmentContainer(WeakReference> env, + BiMap mapProof + ) { + + public KeyEnvironmentContainer(KeYEnvironment env) { + this(new WeakReference<>(env), HashBiMap.create(1)); + } + + void dispose() { + env.clear(); + mapProof.clear(); + } + } + + private record ProofContainer(WeakReference wProof, + BiMap> mapNode, + BiMap> mapTreeNode, + BiMap mapGoalText + ) { + public ProofContainer(Proof proof) { + this(new WeakReference<>(proof), HashBiMap.create(16), HashBiMap.create(16), HashBiMap.create(16)); + } + + void dispose() { + mapNode.clear(); + } + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java index 74c2d9d1cc4..b0c2397d1f3 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java @@ -1,8 +1,15 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record MacroStatistic() { +public record MacroStatistic(KeyIdentifications.ProofId proofId, String macroId, boolean cancelled, int appliedRules, + int closedGoals) { + public static MacroStatistic from(KeyIdentifications.ProofId proofId, ProofMacroFinishedInfo info) { + return new MacroStatistic(proofId, info.getMacro().getName(), info.isCancelled(), + info.getAppliedRules(), info.getClosedGoals()); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java index 9bc8ad0cd04..9e24e0f4cd7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -1,8 +1,18 @@ package org.keyproject.key.api.data; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record NodeDesc() { +public record NodeDesc(KeyIdentifications.NodeId nodeid, String branchLabel, + boolean scriptRuleApplication, + @Nullable List children +) { + public NodeDesc(KeyIdentifications.ProofId proofId, int serialNr, String branchLabel, boolean scriptRuleApplication) { + this(new KeyIdentifications.NodeId(proofId, serialNr), branchLabel, scriptRuleApplication, null); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java deleted file mode 100644 index 3d4893d43e4..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/PrintId.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.data; - -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record PrintId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java new file mode 100644 index 00000000000..31981c61beb --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java @@ -0,0 +1,14 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.macros.ProofMacro; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record ProofMacroDesc(String name, String category, String description, String scriptCommandName) { + public static ProofMacroDesc from(ProofMacro proofMacro) { + return new ProofMacroDesc(proofMacro.getName(), proofMacro.getCategory(), + proofMacro.getDescription(), proofMacro.getScriptCommandName()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java new file mode 100644 index 00000000000..f6eef733d08 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java @@ -0,0 +1,13 @@ +package org.keyproject.key.api.data; + +import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record ProofScriptCommandDesc() { + public static ProofScriptCommandDesc from(ProofScriptCommand proofScriptCommand) { + return null; + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java index b582b4a73f5..66df02ee6b0 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -1,8 +1,19 @@ package org.keyproject.key.api.data; +import de.uka.ilkd.key.logic.sort.Sort; + +import java.util.List; + /** * @author Alexander Weigl * @version 1 (13.10.23) */ -public record SortDesc() { +public record SortDesc(String string, String documentation, + List extendsSorts, + boolean anAbstract, String s) { + public static SortDesc from(Sort sort) { + return new SortDesc(sort.name().toString(), sort.getDocumentation(), + sort.extendsSorts().stream().map(SortDesc::from).toList(), + sort.isAbstract(), sort.declarationString()); + } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java deleted file mode 100644 index b69046120f5..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermAction.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api.data; - -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record TermAction(TermActionId commandId, String displayName) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java new file mode 100644 index 00000000000..b27ac08a279 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java @@ -0,0 +1,11 @@ +package org.keyproject.key.api.data; + +import org.keyproject.key.api.data.KeyIdentifications.TermActionId; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record TermActionDesc(TermActionId commandId, String displayName, String description, String category, + TermActionKind kind) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java index 7951c776af4..96d22acee47 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java @@ -1,8 +1,2 @@ package org.keyproject.key.api.data; -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record TermActionId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java new file mode 100644 index 00000000000..cc7d9aec71a --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.data; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public enum TermActionKind { + BuiltIn, Script, Macro, Taclet +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java index 3dba5cc492e..96d22acee47 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java @@ -1,8 +1,2 @@ package org.keyproject.key.api.data; -/** - * @author Alexander Weigl - * @version 1 (13.10.23) - */ -public record TreeNodeId(String id) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java new file mode 100644 index 00000000000..5750fea944d --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java @@ -0,0 +1,12 @@ +package org.keyproject.key.api.internal; + +import de.uka.ilkd.key.pp.InitialPositionTable; +import de.uka.ilkd.key.pp.PositionTable; +import de.uka.ilkd.key.proof.Node; + +/** + * @author Alexander Weigl + * @version 1 (13.10.23) + */ +public record NodeText(String text, InitialPositionTable table) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java index e82ca44ae28..e84a0152760 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java @@ -1,11 +1,10 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.ContractDesc; +import org.keyproject.key.api.data.FunctionDesc; +import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.SortDesc; import java.util.List; @@ -18,14 +17,14 @@ @JsonSegment("env") public interface EnvApi { @JsonRequest - CompletableFuture> sorts(KeYEnvironment env); + CompletableFuture> sorts(EnvironmentId env); @JsonRequest - CompletableFuture> functions(KeYEnvironment env); + CompletableFuture> functions(EnvironmentId env); @JsonRequest - CompletableFuture> contracts(KeYEnvironment env); + CompletableFuture> contracts(EnvironmentId env); @JsonRequest - CompletableFuture openContract(KeYEnvironment env, String contractId); + CompletableFuture openContract(ContractId contractId); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java index fe678b8f04e..2f34293f0d5 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -1,13 +1,12 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.proof.Node; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.data.GoalText; -import org.keyproject.key.api.data.PrintId; -import org.keyproject.key.api.data.TermAction; -import org.keyproject.key.api.data.TermActionId; +import org.keyproject.key.api.NodeTextDesc; +import org.keyproject.key.api.NodeTextId; +import org.keyproject.key.api.data.*; +import org.keyproject.key.api.data.KeyIdentifications.*; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -19,14 +18,14 @@ @JsonSegment("goal") public interface GoalApi { @JsonRequest - CompletableFuture print(Node id); + CompletableFuture print(NodeId id, PrintOptions options); @JsonRequest - CompletableFuture> actions(PrintId id, int pos); + CompletableFuture> actions(NodeTextId id, int pos); @JsonRequest("apply_action") - CompletableFuture> applyAction(TermActionId id); + CompletableFuture> applyAction(TermActionId id); @JsonNotification("free") - void freePrint(PrintId id); + void freePrint(NodeTextId id); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index ac650359a74..56a166f9af7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -3,5 +3,5 @@ /** * The combined interface that is provided by KeY. */ -public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi { +public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi, ProofLoadApi{ } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java index a4a16b66b02..f101a47f16a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java @@ -1,12 +1,13 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.macros.ProofMacro; -import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.ProofMacroDesc; +import org.keyproject.key.api.data.ProofScriptCommandDesc; import java.util.List; import java.util.concurrent.CompletableFuture; +import org.keyproject.key.api.data.KeyIdentifications.*; @JsonSegment("meta") public interface MetaApi { @@ -14,8 +15,8 @@ public interface MetaApi { CompletableFuture getVersion(); @JsonRequest("available_macros") - CompletableFuture> getAvailableMacros(); + CompletableFuture> getAvailableMacros(); @JsonRequest("available_script_commands") - CompletableFuture>> getAvailableScriptCommands(); + CompletableFuture> getAvailableScriptCommands(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java new file mode 100644 index 00000000000..6555b2a16fb --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.remoteapi; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record PrintOptions(boolean unicode, int width, int indentation, boolean pure, + boolean termLabels) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java index 16c9f390b89..e496b7a4d38 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java @@ -1,9 +1,8 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.proof.Node; -import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.Statistics; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.MacroStatistic; import org.keyproject.key.api.data.NodeDesc; import org.keyproject.key.api.data.StreategyOptions; @@ -17,32 +16,32 @@ */ public interface ProofApi { @JsonRequest - CompletableFuture script(Proof proof, String scriptLine, StreategyOptions options); + CompletableFuture script(ProofId proof, String scriptLine, StreategyOptions options); @JsonRequest - CompletableFuture macro(Proof proof, String macroId, StreategyOptions options); + CompletableFuture macro(ProofId proof, String macroId, StreategyOptions options); @JsonRequest - CompletableFuture auto(Proof proof, StreategyOptions options); + CompletableFuture auto(ProofId proof, StreategyOptions options); @JsonRequest - CompletableFuture dispose(Proof proof); + CompletableFuture dispose(ProofId proof); @JsonRequest - CompletableFuture goals(Proof proof); + CompletableFuture> goals(ProofId proof, boolean onlyOpened, boolean onlyEnabled); @JsonRequest - CompletableFuture tree(Proof proof); + CompletableFuture tree(ProofId proof); @JsonRequest - CompletableFuture root(Proof proof); + CompletableFuture root(ProofId proof); @JsonRequest - CompletableFuture> children(Proof proof, Node nodeId); + CompletableFuture> children(NodeId nodeId); @JsonRequest - CompletableFuture> pruneTo(Proof proof, Node nodeId); + CompletableFuture> pruneTo(NodeId nodeId); @JsonRequest - CompletableFuture statistics(Proof proof); + CompletableFuture statistics(ProofId proof); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java similarity index 50% rename from keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java rename to keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java index 14d737fd5d6..9ffedadf57d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofLoading.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java @@ -1,10 +1,16 @@ -package org.keyproject.key.api.data; +package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; +import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.KeyIdentifications; +import org.keyproject.key.api.data.KeyIdentifications.EnvironmentId; +import org.keyproject.key.api.data.KeyIdentifications.ProofId; +import org.keyproject.key.api.data.LoadParams; +import org.keyproject.key.api.data.ProblemDefinition; import java.util.concurrent.CompletableFuture; @@ -15,20 +21,29 @@ * @since v1 */ @JsonSegment("loading") -public interface ProofLoading { +public interface ProofLoadApi { /** * I am not sure whether this is helpful. Mainly a feature for testing?! * @param id * @return */ @JsonRequest - CompletableFuture loadExample(String id); + CompletableFuture loadExample(String id); /** * */ @JsonRequest - CompletableFuture loadProblem(ProblemDefinition problem); + CompletableFuture loadProblem(ProblemDefinition problem); + + /** + * + */ + @JsonRequest + CompletableFuture loadKey(String content); + + @JsonRequest + CompletableFuture loadTerm(String term); /** * Test! @@ -38,5 +53,5 @@ public interface ProofLoading { * @throws ProblemLoaderException if something went wrong */ @JsonRequest - CompletableFuture> load(LoadParams params) throws ProblemLoaderException; + CompletableFuture> load(LoadParams params) throws ProblemLoaderException; } \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java index 88f5cad0330..d3225919d63 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java @@ -1,10 +1,10 @@ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.KeyIdentifications.ProofId; +import org.keyproject.key.api.data.KeyIdentifications.TreeNodeId; import org.keyproject.key.api.data.TreeNodeDesc; -import org.keyproject.key.api.data.TreeNodeId; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -16,11 +16,11 @@ @JsonSegment("proofTree") public interface ProofTreeApi { @JsonRequest("root") - CompletableFuture treeRoot(Proof id); + CompletableFuture treeRoot(ProofId id); @JsonRequest("children") - CompletableFuture> treeChildren(Proof proof, TreeNodeId nodeId); + CompletableFuture> treeChildren(ProofId proof, TreeNodeId nodeId); @JsonRequest("subtree") - CompletableFuture> treeSubtree(Proof proof, TreeNodeId nodeId); + CompletableFuture> treeSubtree(ProofId proof, TreeNodeId nodeId); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java index a7aebdca1bf..ca086eae72f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -1,5 +1,7 @@ package org.keyproject.key.api.remoteclient; +import de.uka.ilkd.key.prover.TaskFinishedInfo; +import de.uka.ilkd.key.prover.TaskStartedInfo; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; @@ -61,5 +63,10 @@ public interface ClientApi { */ @JsonRequest CompletableFuture showDocument(ShowDocumentParams params); + + + void taskFinished(TaskFinishedInfo info); + void taskProgress(int position); + void taskStarted(TaskStartedInfo info); //endregion } diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java index 1b63674ce67..b275265b6c7 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -1,5 +1,7 @@ package org.keyproject.key.api; +import de.uka.ilkd.key.prover.TaskFinishedInfo; +import de.uka.ilkd.key.prover.TaskStartedInfo; import org.keyproject.key.api.remoteclient.*; import javax.annotation.Nullable; @@ -32,4 +34,19 @@ public CompletableFuture userResponse(ShowMessageRequestParam public CompletableFuture showDocument(ShowDocumentParams params) { return null; } + + @Override + public void taskFinished(TaskFinishedInfo info) { + System.out.println(info); + } + + @Override + public void taskProgress(int position) { + + } + + @Override + public void taskStarted(TaskStartedInfo info) { + System.out.println(info); + } } diff --git a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index edbe4aee393..ae34b339231 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.keyproject.key.api.adapters.KeyAdapter; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; @@ -24,7 +25,7 @@ public class TestRpc { private KeyApi keyApi; @BeforeEach - void setup() throws IOException, ExecutionException, InterruptedException, TimeoutException { + void setup() throws IOException { PipedInputStream inClient = new PipedInputStream(); PipedOutputStream outClient = new PipedOutputStream(); PipedInputStream inServer = new PipedInputStream(); @@ -33,7 +34,9 @@ void setup() throws IOException, ExecutionException, InterruptedException, Timeo inClient.connect(outServer); outClient.connect(inServer); - Launcher serverLauncher = StartServer.launch(outServer, inServer); + KeyApiImpl impl = new KeyApiImpl(new KeyAdapter(null)); + Launcher serverLauncher = StartServer.launch(outServer, inServer, impl); + impl.setClientApi(serverLauncher.getRemoteProxy()); var client = new SimpleClient(); Launcher clientLauncher = new Launcher.Builder() diff --git a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java index 8b8f69d3bf3..5d7647eaf34 100644 --- a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java +++ b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java @@ -3,8 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.exploration; -import java.io.File; - import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.nparser.KeyIO; @@ -12,13 +10,13 @@ import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; - -import org.key_project.util.collection.ImmutableList; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.key_project.util.collection.ImmutableList; + +import java.io.File; import static org.junit.jupiter.api.Assertions.*; @@ -85,7 +83,7 @@ public void testAdditionAntec() { assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -127,7 +125,7 @@ public void testAdditionSucc() { testAddition(withAddedTerm, justification, added, false); assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -148,9 +146,9 @@ public void testChangeFormula() { assertSame(1, goals.size(), "Prerequisite for test"); Sequent sequent = goals.head().node().sequent(); PosInOccurrence pio = - new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); + new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); expService.applyChangeFormula(goals.head(), pio, sequent.succedent().get(0).formula(), - change); + change); ImmutableList newCreatedGoals = currentProof.openGoals(); assertEquals(2, newCreatedGoals.size(), "Two new goals created"); @@ -168,13 +166,16 @@ public void testChangeFormula() { assertNotNull(justificationBranch.node().lookup(ExplorationNodeData.class)); assertEquals(new Name("hide_right"), hideNode.getAppliedRuleApp().rule().name(), - "Hide Right was applied"); + "Hide Right was applied"); // set all goals to interactive justificationBranch.setEnabled(true); // perform proof, it has to close - env.getProofControl().startAndWaitForAutoMode(currentProof, newCreatedGoals); - assertTrue(currentProof.closed(), "Proof is closed"); - + try { + env.getProofControl().startAndWaitForAutoMode(currentProof, newCreatedGoals); + assertTrue(currentProof.closed(), "Proof is closed"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } @@ -183,34 +184,34 @@ public void testChangeFormula() { */ private void testAddition(Goal withAddedTerm, Goal justification, Term added, boolean antec) { Semisequent semiSeqAdded = - antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfAdded = - antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); Semisequent semiSeqUntouched = - !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfUntouched = - !antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + !antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); assertSame(semiSeqAdded.size(), parentSemiSeqOfAdded.size() + 1, - "The size of the added semisequent has changed"); + "The size of the added semisequent has changed"); assertEquals(semiSeqAdded.get(0).formula(), added, "Added Term is indeed added"); assertFalse(justification.isAutomatic(), "Justification branch is marked as interactive"); assertSame(semiSeqUntouched.size(), parentSemiSeqOfUntouched.size(), - "The size if untouched semisequents is the same"); + "The size if untouched semisequents is the same"); assertEquals(semiSeqUntouched, parentSemiSeqOfUntouched, - "The untouched semisequents are equal"); + "The untouched semisequents are equal"); Node parent = withAddedTerm.node().parent(); assertEquals(parent, justification.node().parent(), "Both nodes have the same parent"); assertEquals(new Name("cut"), parent.getAppliedRuleApp().rule().name(), - "The addition was inserted using the cut rule"); + "The addition was inserted using the cut rule"); } /** From 46f0cefe62bbf4b6688d6c8240fd95cc0fcba3af Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 29 Oct 2023 22:44:19 +0100 Subject: [PATCH 15/50] more doc and py generation --- api.meta.json | 1144 +++++++++++++++++ api.meta.md | 480 +++++++ api.py | 374 ++++++ .../main/java/de/uka/ilkd/key/proof/Node.java | 1 + keyext.api.doc/build.gradle | 1 + keyext.api.doc/src/main/java/DocGen.java | 189 +++ .../src/main/java/ExtractMetaData.java | 343 +++-- keyext.api.doc/src/main/java/Metamodel.java | 93 ++ keyext.api.doc/src/main/java/PyGen.java | 136 ++ keyext.api/build.gradle | 6 +- .../org/keyproject/key/api/KeyApiImpl.java | 17 +- .../org/keyproject/key/api/NodeTextDesc.java | 8 - .../org/keyproject/key/api/NodeTextId.java | 6 - .../keyproject/key/api/TermActionUtil.java | 3 +- .../key/api/data/KeyIdentifications.java | 8 +- .../org/keyproject/key/api/data/NodeDesc.java | 5 +- .../keyproject/key/api/data/NodeTextDesc.java | 9 + .../key/api/data/ProblemDefinition.java | 3 +- .../keyproject/key/api/data/TermActionId.java | 2 - .../keyproject/key/api/data/TreeNodeId.java | 2 - .../key/api/remoteapi/ExampleApi.java | 2 +- .../key/api/remoteapi/ExampleDesc.java | 13 + .../keyproject/key/api/remoteapi/GoalApi.java | 3 +- .../key/api/remoteapi/ServerManagement.java | 2 +- keyext.api/src/main/python/keyapi/rpc.py | 76 -- .../java/org/keyproject/key/api/TestRpc.java | 6 +- .../keyapi/__init__.py | 11 +- keyext.client.python/keyapi/rpc.py | 200 +++ .../python => keyext.client.python}/main.py | 0 keyext.client.python/rwtest.py | 402 ++++++ 30 files changed, 3302 insertions(+), 243 deletions(-) create mode 100644 api.meta.json create mode 100644 api.meta.md create mode 100644 api.py create mode 100644 keyext.api.doc/src/main/java/DocGen.java create mode 100644 keyext.api.doc/src/main/java/Metamodel.java create mode 100644 keyext.api.doc/src/main/java/PyGen.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java delete mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java delete mode 100644 keyext.api/src/main/python/keyapi/rpc.py rename {keyext.api/src/main/python => keyext.client.python}/keyapi/__init__.py (54%) create mode 100644 keyext.client.python/keyapi/rpc.py rename {keyext.api/src/main/python => keyext.client.python}/main.py (100%) create mode 100644 keyext.client.python/rwtest.py diff --git a/api.meta.json b/api.meta.json new file mode 100644 index 00000000000..180b16a3019 --- /dev/null +++ b/api.meta.json @@ -0,0 +1,1144 @@ +{ + "endpoints": [ + { + "name": "examples/list", + "documentation": "", + "args": [], + "returnType": { + "type": { + "typeName": "ExampleDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "meta/version", + "documentation": "", + "args": [], + "returnType": "STRING" + }, + { + "name": "meta/available_script_commands", + "documentation": "", + "args": [], + "returnType": { + "type": { + "typeName": "ProofScriptCommandDesc", + "fields": [], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "meta/available_macros", + "documentation": "", + "args": [], + "returnType": { + "type": { + "typeName": "ProofMacroDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "scriptCommandName", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "server/exit", + "documentation": "", + "args": [] + }, + { + "name": "server/shutdown", + "documentation": "", + "args": [], + "returnType": "BOOL" + }, + { + "name": "server/setTrace", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "SetTraceParams" + } + ] + }, + { + "name": "proofTree/root", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProofId" + } + ], + "returnType": { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + } + }, + { + "name": "proofTree/children", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProofId" + }, + { + "name": "arg1", + "type": "TreeNodeId" + } + ], + "returnType": { + "type": { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "proofTree/subtree", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProofId" + }, + { + "name": "arg1", + "type": "TreeNodeId" + } + ], + "returnType": { + "type": { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "goal/print", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "NodeId" + }, + { + "name": "arg1", + "type": "PrintOptions" + } + ], + "returnType": { + "typeName": "NodeTextDesc", + "fields": [ + { + "name": "id", + "type": "NodeTextId" + }, + { + "name": "result", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "goal/actions", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "NodeTextId" + }, + { + "name": "arg1", + "type": "INT" + } + ], + "returnType": { + "type": { + "typeName": "TermActionDesc", + "fields": [ + { + "name": "commandId", + "type": "TermActionId" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "kind", + "type": "TermActionKind" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "goal/apply_action", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "TermActionId" + } + ], + "returnType": { + "type": { + "typeName": "TermActionDesc", + "fields": [ + { + "name": "commandId", + "type": "TermActionId" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "kind", + "type": "TermActionKind" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "goal/free", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "NodeTextId" + } + ] + }, + { + "name": "env/functions", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "EnvironmentId" + } + ], + "returnType": { + "type": { + "typeName": "FunctionDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "sort", + "type": "STRING" + }, + { + "name": "retSort", + "type": "SortDesc" + }, + { + "name": "argSorts", + "type": "List" + }, + { + "name": "rigid", + "type": "BOOL" + }, + { + "name": "unique", + "type": "BOOL" + }, + { + "name": "skolemConstant", + "type": "BOOL" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "env/sorts", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "EnvironmentId" + } + ], + "returnType": { + "type": { + "typeName": "SortDesc", + "fields": [ + { + "name": "string", + "type": "STRING" + }, + { + "name": "documentation", + "type": "STRING" + }, + { + "name": "extendsSorts", + "type": "List" + }, + { + "name": "anAbstract", + "type": "BOOL" + }, + { + "name": "s", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "env/contracts", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "EnvironmentId" + } + ], + "returnType": { + "type": { + "typeName": "ContractDesc", + "fields": [ + { + "name": "contractId", + "type": "ContractId" + }, + { + "name": "name", + "type": "STRING" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "typeName", + "type": "STRING" + }, + { + "name": "htmlText", + "type": "STRING" + }, + { + "name": "plainText", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "env/openContract", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ContractId" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/load", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "LoadParams" + } + ], + "returnType": { + "a": { + "typeName": "EnvironmentId", + "fields": [ + { + "name": "envId", + "type": "STRING" + } + ], + "documentation": "" + }, + "b": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + }, + "documentation": "" + } + }, + { + "name": "loading/loadKey", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/loadExample", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/loadProblem", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ProblemDefinition" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "loading/loadTerm", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ], + "returnType": { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "client/sayHello", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "STRING" + } + ] + }, + { + "name": "client/logTrace", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "LogTraceParams" + } + ] + }, + { + "name": "client/sm", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ShowMessageParams" + } + ] + }, + { + "name": "client/userResponse", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ShowMessageRequestParams" + } + ], + "returnType": { + "typeName": "MessageActionItem", + "fields": [ + { + "name": "title", + "type": "STRING" + } + ], + "documentation": "" + } + }, + { + "name": "client/showDocument", + "documentation": "", + "args": [ + { + "name": "arg0", + "type": "ShowDocumentParams" + } + ], + "returnType": { + "typeName": "ShowDocumentResult", + "fields": [ + { + "name": "success", + "type": "BOOL" + } + ], + "documentation": "" + } + } + ], + "types": [ + { + "typeName": "ExampleDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "ProofScriptCommandDesc", + "fields": [], + "documentation": "" + }, + { + "typeName": "ProofMacroDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "scriptCommandName", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TraceValue", + "values": [ + "Off", + "Message", + "All" + ], + "documentation": "" + }, + { + "typeName": "SetTraceParams", + "fields": [ + { + "name": "value", + "type": "TraceValue" + } + ], + "documentation": "" + }, + { + "typeName": "EnvironmentId", + "fields": [ + { + "name": "envId", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "ProofId", + "fields": [ + { + "name": "env", + "type": "EnvironmentId" + }, + { + "name": "proofId", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TreeNodeDesc", + "fields": [], + "documentation": "" + }, + { + "typeName": "TreeNodeId", + "fields": [ + { + "name": "id", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "NodeId", + "fields": [ + { + "name": "proofId", + "type": "ProofId" + }, + { + "name": "nodeId", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "PrintOptions", + "fields": [ + { + "name": "unicode", + "type": "BOOL" + }, + { + "name": "width", + "type": "INT" + }, + { + "name": "indentation", + "type": "INT" + }, + { + "name": "pure", + "type": "BOOL" + }, + { + "name": "termLabels", + "type": "BOOL" + } + ], + "documentation": "" + }, + { + "typeName": "NodeTextId", + "fields": [ + { + "name": "nodeId", + "type": "NodeId" + }, + { + "name": "nodeTextId", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "NodeTextDesc", + "fields": [ + { + "name": "id", + "type": "NodeTextId" + }, + { + "name": "result", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TermActionId", + "fields": [ + { + "name": "nodeId", + "type": "NodeId" + }, + { + "name": "pio", + "type": "STRING" + }, + { + "name": "id", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "TermActionKind", + "values": [ + "BuiltIn", + "Script", + "Macro", + "Taclet" + ], + "documentation": "" + }, + { + "typeName": "TermActionDesc", + "fields": [ + { + "name": "commandId", + "type": "TermActionId" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "description", + "type": "STRING" + }, + { + "name": "category", + "type": "STRING" + }, + { + "name": "kind", + "type": "TermActionKind" + } + ], + "documentation": "" + }, + { + "typeName": "List", + "fields": [], + "documentation": "" + }, + { + "typeName": "SortDesc", + "fields": [ + { + "name": "string", + "type": "STRING" + }, + { + "name": "documentation", + "type": "STRING" + }, + { + "name": "extendsSorts", + "type": "List" + }, + { + "name": "anAbstract", + "type": "BOOL" + }, + { + "name": "s", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "FunctionDesc", + "fields": [ + { + "name": "name", + "type": "STRING" + }, + { + "name": "sort", + "type": "STRING" + }, + { + "name": "retSort", + "type": "SortDesc" + }, + { + "name": "argSorts", + "type": "List" + }, + { + "name": "rigid", + "type": "BOOL" + }, + { + "name": "unique", + "type": "BOOL" + }, + { + "name": "skolemConstant", + "type": "BOOL" + } + ], + "documentation": "" + }, + { + "typeName": "ContractId", + "fields": [ + { + "name": "envId", + "type": "EnvironmentId" + }, + { + "name": "contractId", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "ContractDesc", + "fields": [ + { + "name": "contractId", + "type": "ContractId" + }, + { + "name": "name", + "type": "STRING" + }, + { + "name": "displayName", + "type": "STRING" + }, + { + "name": "typeName", + "type": "STRING" + }, + { + "name": "htmlText", + "type": "STRING" + }, + { + "name": "plainText", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "LoadParams", + "fields": [ + { + "name": "keyFile", + "type": "STRING" + }, + { + "name": "javaFile", + "type": "STRING" + }, + { + "name": "classPath", + "type": "List" + }, + { + "name": "bootClassPath", + "type": "STRING" + }, + { + "name": "includes", + "type": "List" + } + ], + "documentation": "" + }, + { + "typeName": "ProblemDefinition", + "fields": [ + { + "name": "sorts", + "type": "List" + }, + { + "name": "functions", + "type": "List" + }, + { + "name": "predicates", + "type": "List" + }, + { + "name": "antecTerms", + "type": "List" + }, + { + "name": "succTerms", + "type": "List" + } + ], + "documentation": "" + }, + { + "typeName": "LogTraceParams", + "fields": [ + { + "name": "messag", + "type": "STRING" + }, + { + "name": "verbose", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "MessageType", + "values": [ + "Unused", + "Error", + "Warning", + "Info", + "Log", + "Debug" + ], + "documentation": "" + }, + { + "typeName": "ShowMessageParams", + "fields": [ + { + "name": "type", + "type": "MessageType" + }, + { + "name": "message", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "MessageActionItem[]", + "fields": [], + "documentation": "" + }, + { + "typeName": "ShowMessageRequestParams", + "fields": [ + { + "name": "type", + "type": "MessageType" + }, + { + "name": "message", + "type": "STRING" + }, + { + "name": "actions", + "type": "MessageActionItem[]" + } + ], + "documentation": "" + }, + { + "typeName": "MessageActionItem", + "fields": [ + { + "name": "title", + "type": "STRING" + } + ], + "documentation": "" + }, + { + "typeName": "Range", + "fields": [ + { + "name": "start", + "type": "INT" + }, + { + "name": "end", + "type": "INT" + } + ], + "documentation": "" + }, + { + "typeName": "ShowDocumentParams", + "fields": [ + { + "name": "uri", + "type": "STRING" + }, + { + "name": "external", + "type": "BOOL" + }, + { + "name": "takeFocus", + "type": "BOOL" + }, + { + "name": "selection", + "type": "Range" + } + ], + "documentation": "" + }, + { + "typeName": "ShowDocumentResult", + "fields": [ + { + "name": "success", + "type": "BOOL" + } + ], + "documentation": "" + }, + { + "typeName": "TaskFinishedInfo", + "fields": [], + "documentation": "" + }, + { + "typeName": "TaskStartedInfo", + "fields": [], + "documentation": "" + } + ] +} \ No newline at end of file diff --git a/api.meta.md b/api.meta.md new file mode 100644 index 00000000000..f53d88619f3 --- /dev/null +++ b/api.meta.md @@ -0,0 +1,480 @@ +## Types +### Type: ContractDesc +``` +type ContractDesc { + contractId : ContractId + displayName : STRING + htmlText : STRING + name : STRING + plainText : STRING + typeName : STRING +} +``` + +### Type: ContractId +``` +type ContractId { + contractId : INT + envId : EnvironmentId +} +``` + +### Type: EnvironmentId +``` +type EnvironmentId { + envId : STRING +} +``` + +### Type: ExampleDesc +``` +type ExampleDesc { + description : STRING + name : STRING +} +``` + +### Type: FunctionDesc +``` +type FunctionDesc { + argSorts : List + name : STRING + retSort : SortDesc + rigid : BOOL + skolemConstant : BOOL + sort : STRING + unique : BOOL +} +``` + +### Type: List +``` +type List { + +} +``` + +### Type: LoadParams +``` +type LoadParams { + bootClassPath : STRING + classPath : List + includes : List + javaFile : STRING + keyFile : STRING +} +``` + +### Type: LogTraceParams +``` +type LogTraceParams { + messag : STRING + verbose : STRING +} +``` + +### Type: MessageActionItem +``` +type MessageActionItem { + title : STRING +} +``` + +### Type: MessageActionItem[] +``` +type MessageActionItem[] { + +} +``` + +### Type: MessageType +``` +enum MessageType { Unused, Error, Warning, Info, Log, Debug } +``` + +### Type: NodeId +``` +type NodeId { + nodeId : INT + proofId : ProofId +} +``` + +### Type: NodeTextDesc +``` +type NodeTextDesc { + id : NodeTextId + result : STRING +} +``` + +### Type: NodeTextId +``` +type NodeTextId { + nodeId : NodeId + nodeTextId : INT +} +``` + +### Type: PrintOptions +``` +type PrintOptions { + indentation : INT + pure : BOOL + termLabels : BOOL + unicode : BOOL + width : INT +} +``` + +### Type: ProblemDefinition +``` +type ProblemDefinition { + antecTerms : List + functions : List + predicates : List + sorts : List + succTerms : List +} +``` + +### Type: ProofId +``` +type ProofId { + env : EnvironmentId + proofId : STRING +} +``` + +### Type: ProofMacroDesc +``` +type ProofMacroDesc { + category : STRING + description : STRING + name : STRING + scriptCommandName : STRING +} +``` + +### Type: ProofScriptCommandDesc +``` +type ProofScriptCommandDesc { + +} +``` + +### Type: Range +``` +type Range { + end : INT + start : INT +} +``` + +### Type: SetTraceParams +``` +type SetTraceParams { + value : TraceValue +} +``` + +### Type: ShowDocumentParams +``` +type ShowDocumentParams { + external : BOOL + selection : Range + takeFocus : BOOL + uri : STRING +} +``` + +### Type: ShowDocumentResult +``` +type ShowDocumentResult { + success : BOOL +} +``` + +### Type: ShowMessageParams +``` +type ShowMessageParams { + message : STRING + type : MessageType +} +``` + +### Type: ShowMessageRequestParams +``` +type ShowMessageRequestParams { + actions : MessageActionItem[] + message : STRING + type : MessageType +} +``` + +### Type: SortDesc +``` +type SortDesc { + anAbstract : BOOL + documentation : STRING + extendsSorts : List + s : STRING + string : STRING +} +``` + +### Type: TaskFinishedInfo +``` +type TaskFinishedInfo { + +} +``` + +### Type: TaskStartedInfo +``` +type TaskStartedInfo { + +} +``` + +### Type: TermActionDesc +``` +type TermActionDesc { + category : STRING + commandId : TermActionId + description : STRING + displayName : STRING + kind : TermActionKind +} +``` + +### Type: TermActionId +``` +type TermActionId { + id : STRING + nodeId : NodeId + pio : STRING +} +``` + +### Type: TermActionKind +``` +enum TermActionKind { BuiltIn, Script, Macro, Taclet } +``` + +### Type: TraceValue +``` +enum TraceValue { Off, Message, All } +``` + +### Type: TreeNodeDesc +``` +type TreeNodeDesc { + +} +``` + +### Type: TreeNodeId +``` +type TreeNodeId { + id : STRING +} +``` + +## Endpoints +### client/logTrace (`server ~~> client`) + +``` +Client.client/logTrace( arg0 : LogTraceParams ) **async** +``` + + +### client/sayHello (`server ~~> client`) + +``` +Client.client/sayHello( arg0 : STRING ) **async** +``` + + +### client/showDocument (`server -> client`) + +``` +Client.client/showDocument( arg0 : ShowDocumentParams ) -> ShowDocumentResult +``` + + +### client/sm (`server ~~> client`) + +``` +Client.client/sm( arg0 : ShowMessageParams ) **async** +``` + + +### client/userResponse (`server -> client`) + +``` +Client.client/userResponse( arg0 : ShowMessageRequestParams ) -> MessageActionItem +``` + + +### env/contracts (`client -> server`) + +``` +Server.env/contracts( arg0 : EnvironmentId ) -> ContractDesc[] +``` + + +### env/functions (`client -> server`) + +``` +Server.env/functions( arg0 : EnvironmentId ) -> FunctionDesc[] +``` + + +### env/openContract (`client -> server`) + +``` +Server.env/openContract( arg0 : ContractId ) -> ProofId +``` + + +### env/sorts (`client -> server`) + +``` +Server.env/sorts( arg0 : EnvironmentId ) -> SortDesc[] +``` + + +### examples/list (`client -> server`) + +``` +Server.examples/list( ) -> ExampleDesc[] +``` + + +### goal/actions (`client -> server`) + +``` +Server.goal/actions( arg0 : NodeTextId, arg1 : INT ) -> TermActionDesc[] +``` + + +### goal/apply_action (`client -> server`) + +``` +Server.goal/apply_action( arg0 : TermActionId ) -> TermActionDesc[] +``` + + +### goal/free (`client ~~> server`) + +``` +Server.goal/free( arg0 : NodeTextId ) **async** +``` + + +### goal/print (`client -> server`) + +``` +Server.goal/print( arg0 : NodeId, arg1 : PrintOptions ) -> NodeTextDesc +``` + + +### loading/load (`client -> server`) + +``` +Server.loading/load( arg0 : LoadParams ) -> either +``` + + +### loading/loadExample (`client -> server`) + +``` +Server.loading/loadExample( arg0 : STRING ) -> ProofId +``` + + +### loading/loadKey (`client -> server`) + +``` +Server.loading/loadKey( arg0 : STRING ) -> ProofId +``` + + +### loading/loadProblem (`client -> server`) + +``` +Server.loading/loadProblem( arg0 : ProblemDefinition ) -> ProofId +``` + + +### loading/loadTerm (`client -> server`) + +``` +Server.loading/loadTerm( arg0 : STRING ) -> ProofId +``` + + +### meta/available_macros (`client -> server`) + +``` +Server.meta/available_macros( ) -> ProofMacroDesc[] +``` + + +### meta/available_script_commands (`client -> server`) + +``` +Server.meta/available_script_commands( ) -> ProofScriptCommandDesc[] +``` + + +### meta/version (`client -> server`) + +``` +Server.meta/version( ) -> STRING +``` + + +### proofTree/children (`client -> server`) + +``` +Server.proofTree/children( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +``` + + +### proofTree/root (`client -> server`) + +``` +Server.proofTree/root( arg0 : ProofId ) -> TreeNodeDesc +``` + + +### proofTree/subtree (`client -> server`) + +``` +Server.proofTree/subtree( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +``` + + +### server/exit (`client ~~> server`) + +``` +Server.server/exit( ) **async** +``` + + +### server/setTrace (`client ~~> server`) + +``` +Server.server/setTrace( arg0 : SetTraceParams ) **async** +``` + + +### server/shutdown (`client -> server`) + +``` +Server.server/shutdown( ) -> BOOL +``` + + diff --git a/api.py b/api.py new file mode 100644 index 00000000000..c83050a763e --- /dev/null +++ b/api.py @@ -0,0 +1,374 @@ +import enum +import abc +import typing +class ExampleDesc: + """""" + + name : str + description : str + +class ProofScriptCommandDesc: + """""" + + +class ProofMacroDesc: + """""" + + name : str + category : str + description : str + scriptCommandName : str + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + +class SetTraceParams: + """""" + + value : TraceValue + +class EnvironmentId: + """""" + + envId : str + +class ProofId: + """""" + + env : EnvironmentId + proofId : str + +class TreeNodeDesc: + """""" + + +class TreeNodeId: + """""" + + id : str + +class NodeId: + """""" + + proofId : ProofId + nodeId : int + +class PrintOptions: + """""" + + unicode : bool + width : int + indentation : int + pure : bool + termLabels : bool + +class NodeTextId: + """""" + + nodeId : NodeId + nodeTextId : int + +class NodeTextDesc: + """""" + + id : NodeTextId + result : str + +class TermActionId: + """""" + + nodeId : NodeId + pio : str + id : str + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + +class TermActionDesc: + """""" + + commandId : TermActionId + displayName : str + description : str + category : str + kind : TermActionKind + +class List: + """""" + + +class SortDesc: + """""" + + string : str + documentation : str + extendsSorts : List + anAbstract : bool + s : str + +class FunctionDesc: + """""" + + name : str + sort : str + retSort : SortDesc + argSorts : List + rigid : bool + unique : bool + skolemConstant : bool + +class ContractId: + """""" + + envId : EnvironmentId + contractId : int + +class ContractDesc: + """""" + + contractId : ContractId + name : str + displayName : str + typeName : str + htmlText : str + plainText : str + +class LoadParams: + """""" + + keyFile : str + javaFile : str + classPath : List + bootClassPath : str + includes : List + +class ProblemDefinition: + """""" + + sorts : List + functions : List + predicates : List + antecTerms : List + succTerms : List + +class LogTraceParams: + """""" + + messag : str + verbose : str + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + +class ShowMessageParams: + """""" + + type : MessageType + message : str + +class MessageActionItem[]: + """""" + + +class ShowMessageRequestParams: + """""" + + type : MessageType + message : str + actions : MessageActionItem[] + +class MessageActionItem: + """""" + + title : str + +class Range: + """""" + + start : int + end : int + +class ShowDocumentParams: + """""" + + uri : str + external : bool + takeFocus : bool + selection : Range + +class ShowDocumentResult: + """""" + + success : bool + +class TaskFinishedInfo: + """""" + + +class TaskStartedInfo: + """""" + + +class KeyServer(): + def env_contracts(self, arg0 : EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self.rpc.call_sync("env/contracts", ) + + def env_functions(self, arg0 : EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self.rpc.call_sync("env/functions", ) + + def env_openContract(self, arg0 : ContractId) -> ProofId: + """""" + + return self.rpc.call_sync("env/openContract", ) + + def env_sorts(self, arg0 : EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self.rpc.call_sync("env/sorts", ) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self.rpc.call_sync("examples/list", ) + + def goal_actions(self, arg0 : NodeTextId, arg1 : int) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/actions", ) + + def goal_apply_action(self, arg0 : TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/apply_action", ) + + def goal_free(self, arg0 : NodeTextId): + """""" + + return self.rpc.call_async("goal/free", ) + + def goal_print(self, arg0 : NodeId, arg1 : PrintOptions) -> NodeTextDesc: + """""" + + return self.rpc.call_sync("goal/print", ) + + def loading_load(self, arg0 : LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self.rpc.call_sync("loading/load", ) + + def loading_loadExample(self, arg0 : str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadExample", ) + + def loading_loadKey(self, arg0 : str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadKey", ) + + def loading_loadProblem(self, arg0 : ProblemDefinition) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadProblem", ) + + def loading_loadTerm(self, arg0 : str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadTerm", ) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self.rpc.call_sync("meta/available_macros", ) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self.rpc.call_sync("meta/available_script_commands", ) + + def meta_version(self, ) -> STRING: + """""" + + return self.rpc.call_sync("meta/version", ) + + def proofTree_children(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/children", ) + + def proofTree_root(self, arg0 : ProofId) -> TreeNodeDesc: + """""" + + return self.rpc.call_sync("proofTree/root", ) + + def proofTree_subtree(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/subtree", ) + + def server_exit(self, ): + """""" + + return self.rpc.call_async("server/exit", ) + + def server_setTrace(self, arg0 : SetTraceParams): + """""" + + return self.rpc.call_async("server/setTrace", ) + + def server_shutdown(self, ) -> BOOL: + """""" + + return self.rpc.call_sync("server/shutdown", ) + +class Client(abc.AbcMeta): + @abstractmethod + def client_logTrace(self, arg0 : LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, arg0 : str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, arg0 : ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, arg0 : ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, arg0 : ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass + diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 06da529607f..95ba46fe7be 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -12,6 +12,7 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; +import java.util.stream.Stream; import de.uka.ilkd.key.logic.RenamingTable; import de.uka.ilkd.key.logic.Sequent; diff --git a/keyext.api.doc/build.gradle b/keyext.api.doc/build.gradle index f7aadd6467c..84a1789e01f 100644 --- a/keyext.api.doc/build.gradle +++ b/keyext.api.doc/build.gradle @@ -1,4 +1,5 @@ dependencies { + implementation(project(":keyext.api")) implementation("com.github.javaparser:javaparser-core:3.25.5") implementation("com.github.javaparser:javaparser-symbol-solver-core:3.25.5") } \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/DocGen.java b/keyext.api.doc/src/main/java/DocGen.java new file mode 100644 index 00000000000..36aed393607 --- /dev/null +++ b/keyext.api.doc/src/main/java/DocGen.java @@ -0,0 +1,189 @@ +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class DocGen implements Supplier { + private final Metamodel.KeyApi metamodel; + private PrintWriter out; + private final StringWriter target = new StringWriter(); + + public DocGen(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + printHeader(); + + out.format("## Types%n"); + metamodel.types() + .stream().sorted(Comparator.comparing(Metamodel.Type::name)) + .forEach(this::printType); + + out.format("## Endpoints%n"); + metamodel.endpoints() + .stream().sorted(Comparator.comparing(Metamodel.Endpoint::name)) + .forEach(this::endpoints); + printFooter(); + } + return target.toString(); + } + + private void printFooter() { + + } + + private void printHeader() { + + + } + + private void endpoints(Metamodel.Endpoint endpoint) { + //out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); + //out.println(getJavaDoc(typeDeclaration)); + //out.println("\n"); + + var direction = ""; + if (endpoint instanceof Metamodel.ServerRequest sr) + direction = "client -> server"; + else if (endpoint instanceof Metamodel.ClientRequest sr) + direction = "server -> client"; + else if (endpoint instanceof Metamodel.ServerNotification sr) + direction = "client ~~> server"; + else if (endpoint instanceof Metamodel.ClientNotification sr) + direction = "server ~~> client"; + + out.format("### %s (`%s`) %n%n", endpoint.name(), direction); + out.format("```%n"); + var args = endpoint.args(); + final var a = args.stream() + .map(it -> "%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining(", ")); + if (endpoint instanceof Metamodel.ServerRequest sr) { + out.format("Server.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); + } else if (endpoint instanceof Metamodel.ClientRequest sr) + out.format("Client.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); + else if (endpoint instanceof Metamodel.ServerNotification sr) + out.format("Server.%s( %s ) **async**%n", endpoint.name(), a); + else if (endpoint instanceof Metamodel.ClientNotification sr) + out.format("Client.%s( %s ) **async**%n", endpoint.name(), a); + out.format("```%n"); + + out.println(endpoint.documentation()); + out.println(); + } + + private void printType(Metamodel.Type type) { + out.format("### Type: %s%n", type.name()); + if (type instanceof Metamodel.ObjectType ot) { + out.format(""" + ``` + type %s { + %s + } + ``` + """.formatted(type.name(), + ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) + .map(it -> "\t%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining("\n")))); + } + + if (type instanceof Metamodel.EnumType et) { + out.format(""" + ``` + enum %s { %s } + ``` + """.formatted(type.name(), String.join(", ", et.values()) + )); + out.format(type.documentation()); + } + out.format(type.documentation()); + out.println(); + } + + /* + private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ + var annotationExpr = m.getAnnotationByName("JsonNotification").or( + () -> m.getAnnotationByName("JsonRequest")) + .orElseThrow(); + + var segment = getJsonSegment(td) + "/"; + String name = ""; + + if (annotationExpr.isMarkerAnnotationExpr()) { + name = m.getNameAsString(); + } else if (annotationExpr.isSingleMemberAnnotationExpr()) { + var sma = annotationExpr.asSingleMemberAnnotationExpr(); + name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); + } else { + var ne = annotationExpr.asNormalAnnotationExpr(); + for (MemberValuePair pair : ne.getPairs()) { + switch (pair.getName().asString()) { + case "value": + name = pair.getValue().asLiteralStringValueExpr().getValue(); + break; + case "useSegment": + if (!pair.getValue().asBooleanLiteralExpr().getValue()) { + segment = ""; + } + } + } + } + return segment + name; + } + + @Nonnull + private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ + if (typeDeclaration.getJavadoc().isPresent()) { + final var javadoc = typeDeclaration.getJavadoc().get(); + return javadoc.getDescription().toText() + + "\n\n" + + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) + .collect(Collectors.joining("\n")); + } + return ""; + } + + private static String type (MethodDeclaration method){ + if (method.getAnnotationByName("JsonNotification").isPresent()) + return "notification"; + if (method.getAnnotationByName("JsonRequest").isPresent()) + return "request"; + return ""; + } + + private static boolean isExported (MethodDeclaration method){ + return method.getAnnotationByName("JsonNotification").isPresent() + || method.getAnnotationByName("JsonRequest").isPresent(); + } + + private void printHeader () { + out.format("# KeY-API%n%n"); + } + + private void printFooter () { + } + + + /* + private static boolean hasJsonSegment(TypeDeclaration it) { + return it.getAnnotationByName("JsonSegment").isPresent(); + } + + private static String getJsonSegment(TypeDeclaration it) { + var ae = it.getAnnotationByName("JsonSegment").get(); + return ae.asSingleMemberAnnotationExpr().getMemberValue() + .asLiteralStringValueExpr().getValue(); + } + */ + +} + diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java index a9df59adef8..2855e390f75 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -1,25 +1,27 @@ -import com.github.javaparser.ParseResult; +import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.TypeDeclaration; -import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; -import com.github.javaparser.javadoc.JavadocBlockTag; -import com.github.javaparser.resolution.SymbolResolver; -import com.github.javaparser.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.resolution.typesolvers.TypeSolverBuilder; -import com.github.javaparser.utils.SourceRoot; - -import javax.annotation.Nonnull; -import java.io.FileWriter; +import com.google.gson.*; +import de.uka.ilkd.key.proof.Proof; +import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteclient.ClientApi; +import sun.misc.Unsafe; + +import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.*; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; +import java.util.*; +import java.util.concurrent.CompletableFuture; /** * @author Alexander Weigl @@ -28,135 +30,250 @@ public class ExtractMetaData { private static PrintWriter out; - public static void main(String[] args) throws IOException { - System.out.println("XXX" + Arrays.toString(args)); - ParserConfiguration config = new ParserConfiguration(); - config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); - /*config.setAttributeComments(true); - config.setLexicalPreservationEnabled(false); - config.setStoreTokens(false); - config.setIgnoreAnnotationsWhenAttributingComments(true); - config.setDoNotAssignCommentsPrecedingEmptyLines(true);*/ - //var root = Paths.get(args[0]); - TypeSolver typeSolver = new TypeSolverBuilder() - .withSourceCode("keyext.api/src/main/java") - .withSourceCode("key.core/src/main/java") - .withSourceCode("key.util/src/main/java") - .withCurrentJRE() - .build(); - SymbolResolver symbolResolver = new JavaSymbolSolver(typeSolver); - config.setSymbolResolver(symbolResolver); - var source = new SourceRoot(Paths.get("keyext.api", "src", "main", "java"), config); - var cu = source.tryToParse(); - var jsonSegment = Comparator.comparing(ExtractMetaData::getJsonSegment); - var segments = cu.stream().filter(ParseResult::isSuccessful) - .filter(it -> it.getResult().get().getPrimaryType().isPresent()) - .map(it -> it.getResult().get().getPrimaryType().get()) - .filter(ExtractMetaData::hasJsonSegment) - .sorted(jsonSegment) - .toList(); + private static final List endpoints = new LinkedList<>(); + private static final List types = new LinkedList<>(); + private static final Metamodel.KeyApi keyApi = new Metamodel.KeyApi(endpoints, types); - try (var out = new PrintWriter(new FileWriter("doc.md"))) { - ExtractMetaData.out = out; - printHeader(segments); - segments.forEach(ExtractMetaData::printDocumentation); - printFooter(segments); + public static void main(String[] args) { + for (Method method : KeyApi.class.getMethods()) { + addServerEndpoint(method); } - // "org.keyproject.key.api.remoteapi.KeyApi"; + for (Method method : ClientApi.class.getMethods()) { + addClientEndpoint(method); + } + + try { + Files.writeString(Paths.get("api.meta.json"), getGson().toJson(keyApi)); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + var n = new DocGen(keyApi); + Files.writeString(Paths.get("api.meta.md"), n.get()); + } catch (IOException e) { + e.printStackTrace(); + } + try { + var n = new PyGen(keyApi); + Files.writeString(Paths.get("api.py"), n.get()); + } catch (IOException e) { + e.printStackTrace(); + } } - private static void printDocumentation(TypeDeclaration typeDeclaration) { - out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); - out.println(getJavaDoc(typeDeclaration)); - out.println("\n"); + private static Gson getGson() { + return new GsonBuilder() + .setPrettyPrinting() + .registerTypeAdapter(Type.class, new JsonSerializer() { + @Override + public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject json = (JsonObject) context.serialize(src); + json.addProperty("kind", src.kind()); + return json; + } + }) + .create(); + } - for (MethodDeclaration method : typeDeclaration.getMethods()) { - if (!isExported(method)) continue; + private static void addServerEndpoint(Method method) { + var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); + if (jsonSegment == null) return; + var segment = jsonSegment.value(); - String callName = getCallName(method, typeDeclaration); + var req = method.getAnnotation(JsonRequest.class); + var resp = method.getAnnotation(JsonNotification.class); - out.format("### %s (type: %s) %n%n", callName, type(method)); + var args = translate(method.getParameters()); - out.println(getJavaDoc(method)); + if (req != null) { + var mn = callMethodName(method.getName(), segment, req.value(), req.useSegment()); - out.println(); + if (method.getReturnType() == Void.class) { + System.err.println("Found void as return type for a request! " + method); + return; + } + + var retType = getOrFindType(method.getGenericReturnType()); + Objects.requireNonNull(retType, "No retType found " + method.getGenericReturnType()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ServerRequest(mn, documentation, args, retType); + endpoints.add(mm); + return; + } + + if (resp != null) { + var mn = callMethodName(method.getName(), segment, resp.value(), resp.useSegment()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ServerNotification(mn, documentation, args); + endpoints.add(mm); + return; } + + throw new IllegalStateException(); } - private static String getCallName(MethodDeclaration m, TypeDeclaration td) { - var annotationExpr = m.getAnnotationByName("JsonNotification").or( - () -> m.getAnnotationByName("JsonRequest")) - .orElseThrow(); + private static String findDocumentation(Method method) { + // TODO get compilation, get type, find method, getJavaDocComment() + return ""; + } - var segment = getJsonSegment(td) + "/"; - String name = ""; + private static List translate(Parameter[] parameters) { + return Arrays.stream(parameters).map(ExtractMetaData::translate).toList(); + } - if (annotationExpr.isMarkerAnnotationExpr()) { - name = m.getNameAsString(); - } else if (annotationExpr.isSingleMemberAnnotationExpr()) { - var sma = annotationExpr.asSingleMemberAnnotationExpr(); - name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); - } else { - var ne = annotationExpr.asNormalAnnotationExpr(); - for (MemberValuePair pair : ne.getPairs()) { - switch (pair.getName().asString()) { - case "value": - name = pair.getValue().asLiteralStringValueExpr().getValue(); - break; - case "useSegment": - if (!pair.getValue().asBooleanLiteralExpr().getValue()) { - segment = ""; - } - } - } - } - return segment + name; + private static Metamodel.Argument translate(Parameter parameter) { + var type = getOrFindType(parameter.getType()).name(); + return new Metamodel.Argument(parameter.getName(), type); } + private static Metamodel.Type getOrFindType(Class type) { + System.out.println(type); + if (type == CompletableFuture.class) { + return getOrFindType(type.getTypeParameters()[0].getClass()); + } - @Nonnull - private static String getJavaDoc(NodeWithJavadoc typeDeclaration) { - if (typeDeclaration.getJavadoc().isPresent()) { - final var javadoc = typeDeclaration.getJavadoc().get(); - return javadoc.getDescription().toText() - + "\n\n" - + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) - .collect(Collectors.joining("\n")); + if (type == Unsafe.class || type == Class.class || type == Constructor.class || type == Proof.class) { + throw new IllegalStateException("Forbidden class reached!"); } - return ""; + + if (type == String.class) return Metamodel.BuiltinType.STRING; + if (type == Integer.class) return Metamodel.BuiltinType.INT; + if (type == Double.class) return Metamodel.BuiltinType.DOUBLE; + if (type == Long.class) return Metamodel.BuiltinType.LONG; + if (type == Character.class) return Metamodel.BuiltinType.LONG; + if (type == File.class) return Metamodel.BuiltinType.STRING; + if (type == Boolean.class) return Metamodel.BuiltinType.BOOL; + if (type == Boolean.TYPE) return Metamodel.BuiltinType.BOOL; + + if (type == Integer.TYPE) return Metamodel.BuiltinType.INT; + if (type == Double.TYPE) return Metamodel.BuiltinType.DOUBLE; + if (type == Long.TYPE) return Metamodel.BuiltinType.LONG; + if (type == Character.TYPE) return Metamodel.BuiltinType.LONG; + + System.out.println(type); + var t = types.stream().filter(it -> it.name().equals(type.getSimpleName())).findFirst(); + if (t.isPresent()) return t.get(); + var a = createType(type); + types.add(a); + return a; } - private static String type(MethodDeclaration method) { - if (method.getAnnotationByName("JsonNotification").isPresent()) - return "notification"; - if (method.getAnnotationByName("JsonRequest").isPresent()) - return "request"; - return ""; + private static Metamodel.Type createType(Class type) { + final var documentation = findDocumentation(type); + if (type.isEnum()) + return new Metamodel.EnumType(type.getSimpleName(), + Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), + documentation); + + + var obj = new Metamodel.ObjectType(type.getSimpleName(), new ArrayList<>(), documentation); + final var list = Arrays.stream(type.getDeclaredFields()) + .map(it -> new Metamodel.Field(it.getName(), getOrFindType(it.getType()).name())) + .toList(); + obj.fields().addAll(list); + return obj; } - private static boolean isExported(MethodDeclaration method) { - return method.getAnnotationByName("JsonNotification").isPresent() - || method.getAnnotationByName("JsonRequest").isPresent(); + private static String findDocumentation(Class type) { + var parser = initJavaParser(); + var fileName = findFileForType(type); + + if (Files.exists(fileName)) { + try { + return parser.parse(fileName).getResult().flatMap(CompilationUnit::getPrimaryType) + .flatMap(NodeWithJavadoc::getJavadocComment) + .map(Comment::getContent).orElse(""); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } else return ""; } - private static void printHeader(List> segments) { - out.format("# KeY-API%n%n"); + private static Path findFileForType(Class type) { + final var folderString = type.getPackageName().replaceAll("\\.", "/"); + var folder = Paths.get("keyext.api", "src", "main", "java", folderString); + final Class declaringClass = type.getDeclaringClass(); + var fileName = (declaringClass != null ? declaringClass : type).getSimpleName() + ".java"; + var file = folder.resolve(fileName); + return file; } - private static void printFooter(List> segments) { + private static void addClientEndpoint(Method method) { + var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); + var segment = jsonSegment.value(); + + var req = method.getAnnotation(JsonRequest.class); + var resp = method.getAnnotation(JsonNotification.class); + + var args = translate(method.getParameters()); + + if (req != null) { + var retType = getOrFindType(method.getGenericReturnType()); + Objects.requireNonNull(retType); + var mn = callMethodName(method.getName(), segment, req.value(), req.useSegment()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ClientRequest(mn, documentation, args, retType); + endpoints.add(mm); + return; + } + + if (resp != null) { + var mn = callMethodName(method.getName(), segment, resp.value(), resp.useSegment()); + var documentation = findDocumentation(method); + var mm = new Metamodel.ClientNotification(mn, documentation, args); + endpoints.add(mm); + } + } + private static String callMethodName(String method, String segment, String userValue, boolean useSegment) { + if (!useSegment) { + if (userValue == null || userValue.isBlank()) { + return method; + } else { + return userValue; + } + } else { + if (userValue == null || userValue.isBlank()) { + return segment + "/" + method; + } else { + return segment + "/" + userValue; + } + } } + private static Metamodel.Type getOrFindType(Type genericReturnType) { + if (genericReturnType instanceof Class c) return getOrFindType(c); + if (genericReturnType instanceof ParameterizedType pt) { + if (Objects.equals(pt.getRawType().getTypeName(), CompletableFuture.class.getTypeName())) { + return getOrFindType(pt.getActualTypeArguments()[0]); + } + if (Objects.equals(pt.getRawType().getTypeName(), List.class.getTypeName())) { + var base = getOrFindType(pt.getActualTypeArguments()[0]); + return new Metamodel.ListType(base, ""); + } - private static boolean hasJsonSegment(TypeDeclaration it) { - return it.getAnnotationByName("JsonSegment").isPresent(); + if (Objects.equals(pt.getRawType().getTypeName(), Either.class.getTypeName())) { + var base1 = getOrFindType(pt.getActualTypeArguments()[0]); + var base2 = getOrFindType(pt.getActualTypeArguments()[1]); + return new Metamodel.EitherType(base1, base2, ""); + } + } + return null; } - private static String getJsonSegment(TypeDeclaration it) { - var ae = it.getAnnotationByName("JsonSegment").get(); - return ae.asSingleMemberAnnotationExpr().getMemberValue() - .asLiteralStringValueExpr().getValue(); + static JavaParser initJavaParser() { + ParserConfiguration config = new ParserConfiguration(); + config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); + config.setAttributeComments(true); + config.setLexicalPreservationEnabled(false); + config.setStoreTokens(false); + config.setIgnoreAnnotationsWhenAttributingComments(true); + config.setDoNotAssignCommentsPrecedingEmptyLines(true); + return new JavaParser(config); } + } diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/Metamodel.java new file mode 100644 index 00000000000..833699cfe0c --- /dev/null +++ b/keyext.api.doc/src/main/java/Metamodel.java @@ -0,0 +1,93 @@ +import org.jspecify.annotations.NullMarked; + +import java.util.List; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +@NullMarked +public class Metamodel { + public record KeyApi( + List endpoints, + List types + ) { + } + + sealed interface Endpoint { + String name(); + + String documentation(); + + default String kind() { + return getClass().getSimpleName(); + } + + List args(); + } + + public record Argument(String name, String type) { + } + + record ServerRequest(String name, String documentation, List args, Type returnType) implements Endpoint { + } + + record ServerNotification(String name, String documentation, List args) implements Endpoint { + } + + record ClientRequest(String name, String documentation, List args, Type returnType) implements Endpoint { + } + + record ClientNotification(String name, String documentation, List args) implements Endpoint { + } + + record Field(String name, /*Type*/ String type) { + } + + sealed interface Type { + default String kind() { + return getClass().getSimpleName(); + } + + String documentation(); + + String name(); + } + + enum BuiltinType implements Type { + INT, LONG, STRING, BOOL, DOUBLE; + + @Override + public String documentation() { + return "built-in data type"; + } + } + + record ListType(Type type, String documentation) implements Type { + @Override + public String name() { + return type().name() + "[]"; + } + } + + record ObjectType(String typeName, List fields, String documentation) implements Type { + @Override + public String name() { + return typeName; + } + } + + public record EitherType(Type a, Type b, String documentation) implements Type { + @Override + public String name() { + return "either"; + } + } + + public record EnumType(String typeName, List values, String documentation) implements Type { + @Override + public String name() { + return typeName; + } + } +} diff --git a/keyext.api.doc/src/main/java/PyGen.java b/keyext.api.doc/src/main/java/PyGen.java new file mode 100644 index 00000000000..357c2f51e8d --- /dev/null +++ b/keyext.api.doc/src/main/java/PyGen.java @@ -0,0 +1,136 @@ +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class PyGen implements Supplier { + private final Metamodel.KeyApi metamodel; + private PrintWriter out; + private final StringWriter target = new StringWriter(); + + public PyGen(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + + out.format(""" + import enum + import abc + import typing + from abc import abstractmethod + """); + + metamodel.types().forEach(this::printType); + server( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + + client( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + + } + return target.toString(); + } + + private void client(Stream sorted) { + out.format("class Client(abc.AbcMeta):%n"); + sorted.forEach(this::clientEndpoint); + } + + private void clientEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + out.format(" @abstractmethod%n"); + if (endpoint instanceof Metamodel.ClientRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, asPython(sr.returnType())); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + } + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" pass".formatted(endpoint.name(), "")); + out.println(); + out.println(); + } + + private void server(Stream sorted) { + out.format("class KeyServer():%n"); + sorted.forEach(this::serverEndpoint); + } + + private void serverEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + if (endpoint instanceof Metamodel.ServerRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, + asPython(sr.returnType())); + out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); + out.format(" return self.rpc.call_sync(\"%s\", %s)".formatted(endpoint.name(), "")); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" return self.rpc.call_async(\"%s\", %s)".formatted(endpoint.name(), "")); + } + out.println(); + out.println(); + } + + private void printType(Metamodel.Type type) { + if (type instanceof Metamodel.ObjectType ot) { + out.format("class %s:%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); + ot.fields().forEach(it -> out.format(" %s : %s%n".formatted(it.name(), asPython(it.type())))); + } else if (type instanceof Metamodel.EnumType et) { + out.format("class %s(enum.Enum):%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); + et.values().forEach(it -> out.format(" %s = None%n".formatted(it))); + } + out.println(); + } + + private String asPython(String typeName) { + return switch (typeName) { + case "INT" -> "int"; + case "LONG" -> "int"; + case "STRING" -> "str"; + case "BOOL" -> "bool"; + case "DOUBLE" -> "float"; + default -> { + var t = findType(typeName); + yield asPython(t); + } + }; + } + + private String asPython(Metamodel.Type t) { + if (t instanceof Metamodel.ListType lt) { + return "typing.List[" + asPython(lt.type()) + "]"; + } + + if (t instanceof Metamodel.EitherType lt) { + return "typing.Union[" + asPython(lt.a()) + ", " + asPython(lt.b()) + "]"; + } + return t.name(); + } + + private Metamodel.Type findType(String typeName) { + return this.metamodel.types().stream().filter(it -> it.name().equals(typeName)).findFirst() + .orElseThrow(() -> new RuntimeException("Could not find type: " + typeName)); + } +} \ No newline at end of file diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index c2b84249430..fbbbac93898 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -10,10 +10,10 @@ plugins { description "Verification server interface via JSON-RPC" dependencies { - implementation(project(":key.core")) - implementation(project(":key.ui")) + api(project(":key.core")) + api(project(":key.ui")) - implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") + api("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.1") implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.websocket.jakarta:0.21.1") implementation("org.eclipse.jetty.websocket:websocket-javax-server:10.0.16") diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index fd1b8352356..7ff86ae2c09 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -3,7 +3,6 @@ import de.uka.ilkd.key.control.AbstractUserInterfaceControl; import de.uka.ilkd.key.control.DefaultUserInterfaceControl; import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.gui.Example; import de.uka.ilkd.key.gui.ExampleChooser; import de.uka.ilkd.key.macros.ProofMacroFacade; import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; @@ -32,6 +31,7 @@ import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.internal.NodeText; +import org.keyproject.key.api.remoteapi.ExampleDesc; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteapi.PrintOptions; import org.keyproject.key.api.remoteclient.ClientApi; @@ -73,13 +73,14 @@ public KeyApiImpl() { @Override @JsonRequest - public CompletableFuture> examples() { - return CompletableFutures.computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples())); + public CompletableFuture> examples() { + return CompletableFutures.computeAsync((c) -> + ExampleChooser.listExamples(ExampleChooser.lookForExamples()).stream().map(it -> ExampleDesc.from(it)).toList()); } @Override - public CompletableFuture shutdown() { - return CompletableFuture.completedFuture(null); + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(true); } @Override @@ -192,7 +193,8 @@ private List asNodeDesc(ProofId proofId, Stream nodes) { } private NodeDesc asNodeDesc(ProofId proofId, Node it) { - return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), it.getNodeInfo().getScriptRuleApplication()); + return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), + it.getNodeInfo().getScriptRuleApplication()); } @Override @@ -204,10 +206,11 @@ public CompletableFuture tree(ProofId proofId) { } private NodeDesc asNodeDescRecursive(ProofId proofId, Node root) { + final List list = root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList(); return new NodeDesc(new NodeId(proofId, root.serialNr()), root.getNodeInfo().getBranchLabel(), root.getNodeInfo().getScriptRuleApplication(), - root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList() + list ); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java deleted file mode 100644 index 0a27c633e5a..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextDesc.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.keyproject.key.api; - -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public record NodeTextDesc(NodeTextId id, String result) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java index a99bed5fda9..f28001e8c15 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java @@ -2,9 +2,3 @@ import org.keyproject.key.api.data.KeyIdentifications.NodeId; -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public record NodeTextId(NodeId nodeId, int nodeTextId) { -} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java index 51e0053eed6..31714a361d7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -9,10 +9,11 @@ import de.uka.ilkd.key.pp.PosInSequent; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.*; -import org.checkerframework.checker.nullness.qual.NonNull; +import org.jspecify.annotations.NonNull; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; import org.keyproject.key.api.data.KeyIdentifications; +import org.keyproject.key.api.data.KeyIdentifications.NodeTextId; import org.keyproject.key.api.data.TermActionDesc; import org.keyproject.key.api.data.TermActionKind; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java index 0698a50a982..6d66823142a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java @@ -5,8 +5,7 @@ import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.keyproject.key.api.NodeTextId; +import org.jspecify.annotations.NonNull; import org.keyproject.key.api.internal.NodeText; import java.lang.ref.WeakReference; @@ -109,11 +108,12 @@ public record ProofId(EnvironmentId env, String proofId) { /** * @author Alexander Weigl - * @version 1 (13.10.23) + * @version 1 (29.10.23) */ - public record PrintId(String id) { + public record NodeTextId(NodeId nodeId, int nodeTextId) { } + /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java index 9e24e0f4cd7..eda5e693f64 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -1,6 +1,6 @@ package org.keyproject.key.api.data; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; import java.util.List; @@ -8,7 +8,8 @@ * @author Alexander Weigl * @version 1 (13.10.23) */ -public record NodeDesc(KeyIdentifications.NodeId nodeid, String branchLabel, +public record NodeDesc(KeyIdentifications.NodeId nodeid, + String branchLabel, boolean scriptRuleApplication, @Nullable List children ) { diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java new file mode 100644 index 00000000000..333b24f1c73 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java @@ -0,0 +1,9 @@ +package org.keyproject.key.api.data; + + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record NodeTextDesc(KeyIdentifications.NodeTextId id, String result) { +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java index 4e2de0d4010..d952ea3a654 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java @@ -1,6 +1,7 @@ package org.keyproject.key.api.data; -import org.checkerframework.checker.nullness.qual.Nullable; + +import org.jspecify.annotations.Nullable; import java.util.List; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java deleted file mode 100644 index 96d22acee47..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionId.java +++ /dev/null @@ -1,2 +0,0 @@ -package org.keyproject.key.api.data; - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java deleted file mode 100644 index 96d22acee47..00000000000 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeId.java +++ /dev/null @@ -1,2 +0,0 @@ -package org.keyproject.key.api.data; - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java index 9ccbb03049f..6c52dfd39aa 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java @@ -10,5 +10,5 @@ @JsonSegment("examples") public interface ExampleApi { @JsonRequest("list") - CompletableFuture> examples(); + CompletableFuture> examples(); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java new file mode 100644 index 00000000000..c0091943899 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java @@ -0,0 +1,13 @@ +package org.keyproject.key.api.remoteapi; + +import de.uka.ilkd.key.gui.Example; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public record ExampleDesc(String name, String description) { + public static ExampleDesc from(Example example) { + return new ExampleDesc(example.getName(), example.getDescription()); + } +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java index 2f34293f0d5..959ed91570c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -3,8 +3,7 @@ import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.NodeTextDesc; -import org.keyproject.key.api.NodeTextId; +import org.keyproject.key.api.data.NodeTextDesc; import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java index ddd1fe408e6..00e85b9e021 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java @@ -29,7 +29,7 @@ public interface ServerManagement { * error: code and message set in case an exception happens during shutdown request. */ @JsonRequest - CompletableFuture shutdown(); + CompletableFuture shutdown(); /** * Exit Notification (:arrow_right:) diff --git a/keyext.api/src/main/python/keyapi/rpc.py b/keyext.api/src/main/python/keyapi/rpc.py deleted file mode 100644 index 89dc6f3e041..00000000000 --- a/keyext.api/src/main/python/keyapi/rpc.py +++ /dev/null @@ -1,76 +0,0 @@ -import abc -import json -from abc import abstractmethod -from multiprocessing import Process, SimpleQueue, Lock, Value - - -class Client(abc.ABC): - @abstractmethod - def handle(self, response): - pass - - -class JsonRPCHandler: - client: Client - - def __init__(self, in_stream, out_stream): - self.input = in_stream - self.out = out_stream - self.__id = 0 - self.client: Client - - self._events = dict() - self._responses = dict() - - # t: Process = Process(target=self.__read) - # t.start() - - def read_message(self): - length = 0 - for clength in self.input.readlines(): - if clength.startswith("Content-Length:"): - length = int(clength[14:]) - break - - payload = self.input.read(2 + length) - r = json.loads(payload) - if "id" in r: # JSON response for request - rid = r["id"] - # self._responses[rid] = r - # if rid in self._events: - # self._events[rid].set() - else: # JSON notification - self.client.handle(r) - return r - - def __read(self): - while True: - self.read_message() - - # def __create_event(self, number): - # self._events[number] = Event() - - def _send(self, method, params): - self.__id += 1 - id = self.__id - # self.__create_event(self.__id) - req = {"jsonrpc": "2.0", "method": method, "params": params, "id": self.__id} - - self._write(json.dumps(req)) - # self._wait_for(self.__id) - - r = dict() - while "id" in r and str(r[id]) != str(id): - r = self.read_message() - return r - - def _write(self, msg): - length = len(msg) - self.out.write(f"Content-Length: {length}\r\n") - self.out.write("\r\n") - self.out.write(msg) - self.out.write("\r\n") - self.out.flush() - - # def _wait_for(self, rid): - # self._events[rid].wait() diff --git a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index ae34b339231..5e0c87e06f5 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.keyproject.key.api.adapters.KeyAdapter; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; @@ -16,7 +15,6 @@ import java.util.Collections; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,7 +32,7 @@ void setup() throws IOException { inClient.connect(outServer); outClient.connect(inServer); - KeyApiImpl impl = new KeyApiImpl(new KeyAdapter(null)); + KeyApiImpl impl = new KeyApiImpl(); Launcher serverLauncher = StartServer.launch(outServer, inServer, impl); impl.setClientApi(serverLauncher.getRemoteProxy()); @@ -58,7 +56,7 @@ void setup() throws IOException { } @AfterEach - void teardown() throws ExecutionException, InterruptedException, TimeoutException { + void teardown() { serverListening.cancel(true); clientListening.cancel(true); } diff --git a/keyext.api/src/main/python/keyapi/__init__.py b/keyext.client.python/keyapi/__init__.py similarity index 54% rename from keyext.api/src/main/python/keyapi/__init__.py rename to keyext.client.python/keyapi/__init__.py index 8523f3801f5..4a913b39b2e 100644 --- a/keyext.api/src/main/python/keyapi/__init__.py +++ b/keyext.client.python/keyapi/__init__.py @@ -1,13 +1,4 @@ -from keyapi.rpc import JsonRPCHandler, Client - - -class KeyClient(Client): - def __int__(self): - pass - - def handle(self, res): - print(res) - +from keyapi.rpc import * class KeyStub(JsonRPCHandler): def __init__(self, input, output): diff --git a/keyext.client.python/keyapi/rpc.py b/keyext.client.python/keyapi/rpc.py new file mode 100644 index 00000000000..02ba2be474b --- /dev/null +++ b/keyext.client.python/keyapi/rpc.py @@ -0,0 +1,200 @@ +import enum +import json +import sys +import threading +from io import TextIOWrapper +from typing import Dict + +JSON_RPC_REQ_FORMAT = "Content-Length: {json_string_len}\r\n\r\n{json_string}" +LEN_HEADER = "Content-Length: " +TYPE_HEADER = "Content-Type: " + + +class MyEncoder(json.JSONEncoder): + """ + Encodes an object in JSON + """ + + def default(self, o): # pylint: disable=E0202 + return o.__dict__ + + +class ResponseError(Exception): + def __init__(self, error_code, message): + super().__init__(message) + self.error_code = error_code + + +class ErrorCodes(enum.Enum): + ParseError = 1 + + +class JsonRpcEndpoint(object): + ''' + Thread safe JSON RPC endpoint implementation. Responsible to recieve and send JSON RPC messages, as described in the + protocol. More information can be found: https://www.jsonrpc.org/ + ''' + + def __init__(self, stdin, stdout): + self.stdin = stdin + self.stdout = stdout + self.read_lock = threading.Lock() + self.write_lock = threading.Lock() + + @staticmethod + def __add_header(json_string): + ''' + Adds a header for the given json string + + :param str json_string: The string + :return: the string with the header + ''' + return JSON_RPC_REQ_FORMAT.format(json_string_len=len(json_string), json_string=json_string) + + def send_request(self, message): + ''' + Sends the given message. + + :param dict message: The message to send. + ''' + json_string = json.dumps(message, cls=MyEncoder) + jsonrpc_req = self.__add_header(json_string) + with self.write_lock: + self.stdin.write(jsonrpc_req.encode()) + self.stdin.flush() + + def recv_response(self): + ''' + Recives a message. + + :return: a message + ''' + with self.read_lock: + message_size = None + while True: + # read header + line = self.stdout.readline() + if not line: + # server quit + return None + line = line.decode("utf-8") + if not line.endswith("\r\n"): + raise ResponseError(ErrorCodes.ParseError, "Bad header: missing newline") + # remove the "\r\n" + line = line[:-2] + if line == "": + # done with the headers + break + elif line.startswith(LEN_HEADER): + line = line[len(LEN_HEADER):] + if not line.isdigit(): + raise ResponseError(ErrorCodes.ParseError, + "Bad header: size is not int") + message_size = int(line) + elif line.startswith(TYPE_HEADER): + # nothing todo with type for now. + pass + else: + raise ResponseError(ErrorCodes.ParseError, "Bad header: unkown header") + if not message_size: + raise ResponseError(ErrorCodes.ParseError, "Bad header: missing size") + + jsonrpc_res = self.stdout.read(message_size).decode("utf-8") + return json.loads(jsonrpc_res) + + +class LspEndpoint(threading.Thread): + def __init__(self, json_rpc_endpoint: JsonRpcEndpoint, method_callbacks=None, notify_callbacks=None, timeout=2): + super().__init__() + self.json_rpc_endpoint: JsonRpcEndpoint = json_rpc_endpoint + self.notify_callbacks: Dict = notify_callbacks or {} + self.method_callbacks: Dict = method_callbacks or {} + self.event_dict = {} + self.response_dict = {} + self.next_id = 0 + self._timeout = timeout + self.shutdown_flag = False + + def handle_result(self, rpc_id, result, error): + self.response_dict[rpc_id] = (result, error) + cond = self.event_dict[rpc_id] + cond.acquire() + cond.notify() + cond.release() + + def stop(self): + self.shutdown_flag = True + + def run(self): + while not self.shutdown_flag: + try: + jsonrpc_message = self.json_rpc_endpoint.recv_response() + if jsonrpc_message is None: + print("server quit") + break + method = jsonrpc_message.get("method") + result = jsonrpc_message.get("result") + error = jsonrpc_message.get("error") + rpc_id = jsonrpc_message.get("id") + params = jsonrpc_message.get("params") + + if method: + if rpc_id: + # a call for method + if method not in self.method_callbacks: + raise ResponseError(ErrorCodes.MethodNotFound, + "Method not found: {method}".format(method=method)) + result = self.method_callbacks[method](params) + self.send_response(rpc_id, result, None) + else: + # a call for notify + if method not in self.notify_callbacks: + # Have nothing to do with this. + print("Notify method not found: {method}.".format(method=method)) + else: + self.notify_callbacks[method](params) + else: + self.handle_result(rpc_id, result, error) + except ResponseError as e: + self.send_response(rpc_id, None, e) + + def send_response(self, id, result, error): + message_dict = {"jsonrpc": "2.0", "id": id} + if result: + message_dict["result"] = result + if error: + message_dict["error"] = error + self.json_rpc_endpoint.send_request(message_dict) + + def send_message(self, method_name, params, id=None): + message_dict = {} + message_dict["jsonrpc"] = "2.0" + if id is not None: + message_dict["id"] = id + message_dict["method"] = method_name + message_dict["params"] = params + self.json_rpc_endpoint.send_request(message_dict) + + def call_method(self, method_name, **kwargs): + current_id = self.next_id + self.next_id += 1 + cond = threading.Condition() + self.event_dict[current_id] = cond + + cond.acquire() + self.send_message(method_name, kwargs, current_id) + if self.shutdown_flag: + return None + + if not cond.wait(timeout=self._timeout): + raise TimeoutError() + cond.release() + + self.event_dict.pop(current_id) + result, error = self.response_dict.pop(current_id) + if error: + raise ResponseError(error.get("code"), error.get("message"), error.get("data")) + return result + + def send_notification(self, method_name, **kwargs): + self.send_message(method_name, kwargs) diff --git a/keyext.api/src/main/python/main.py b/keyext.client.python/main.py similarity index 100% rename from keyext.api/src/main/python/main.py rename to keyext.client.python/main.py diff --git a/keyext.client.python/rwtest.py b/keyext.client.python/rwtest.py new file mode 100644 index 00000000000..312532192dc --- /dev/null +++ b/keyext.client.python/rwtest.py @@ -0,0 +1,402 @@ +import enum +import abc +import typing +from abc import abstractmethod + + +class ExampleDesc: + """""" + + name: str + description: str + + +class ProofScriptCommandDesc: + """""" + + +class ProofMacroDesc: + """""" + + name: str + category: str + description: str + scriptCommandName: str + + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + + +class SetTraceParams: + """""" + + value: TraceValue + + +class EnvironmentId: + """""" + + envId: str + + +class ProofId: + """""" + + env: EnvironmentId + proofId: str + + +class TreeNodeDesc: + """""" + + +class TreeNodeId: + """""" + + id: str + + +class NodeId: + """""" + + proofId: ProofId + nodeId: int + + +class PrintOptions: + """""" + + unicode: bool + width: int + indentation: int + pure: bool + termLabels: bool + + +class NodeTextId: + """""" + + nodeId: NodeId + nodeTextId: int + + +class NodeTextDesc: + """""" + + id: NodeTextId + result: str + + +class TermActionId: + """""" + + nodeId: NodeId + pio: str + id: str + + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + + +class TermActionDesc: + """""" + + commandId: TermActionId + displayName: str + description: str + category: str + kind: TermActionKind + + +class List: + """""" + + +class SortDesc: + """""" + + string: str + documentation: str + extendsSorts: List + anAbstract: bool + s: str + + +class FunctionDesc: + """""" + + name: str + sort: str + retSort: SortDesc + argSorts: List + rigid: bool + unique: bool + skolemConstant: bool + + +class ContractId: + """""" + + envId: EnvironmentId + contractId: int + + +class ContractDesc: + """""" + + contractId: ContractId + name: str + displayName: str + typeName: str + htmlText: str + plainText: str + + +class LoadParams: + """""" + + keyFile: str + javaFile: str + classPath: List + bootClassPath: str + includes: List + + +class ProblemDefinition: + """""" + + sorts: List + functions: List + predicates: List + antecTerms: List + succTerms: List + + +class LogTraceParams: + """""" + + messag: str + verbose: str + + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + + +class ShowMessageParams: + """""" + + type: MessageType + message: str + + + +class ShowMessageRequestParams: + """""" + + type: MessageType + message: str + actions: typing.List[MessageActionItem] + + +class MessageActionItem: + """""" + + title: str + + +class Range: + """""" + + start: int + end: int + + +class ShowDocumentParams: + """""" + + uri: str + external: bool + takeFocus: bool + selection: Range + + +class ShowDocumentResult: + """""" + + success: bool + + +class TaskFinishedInfo: + """""" + + +class TaskStartedInfo: + """""" + + +class KeyServer(): + def env_contracts(self, arg0: EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self.rpc.call_sync("env/contracts", ) + + def env_functions(self, arg0: EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self.rpc.call_sync("env/functions", ) + + def env_openContract(self, arg0: ContractId) -> ProofId: + """""" + + return self.rpc.call_sync("env/openContract", ) + + def env_sorts(self, arg0: EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self.rpc.call_sync("env/sorts", ) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self.rpc.call_sync("examples/list", ) + + def goal_actions(self, arg0: NodeTextId, arg1: int) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/actions", ) + + def goal_apply_action(self, arg0: TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self.rpc.call_sync("goal/apply_action", ) + + def goal_free(self, arg0: NodeTextId): + """""" + + return self.rpc.call_async("goal/free", ) + + def goal_print(self, arg0: NodeId, arg1: PrintOptions) -> NodeTextDesc: + """""" + + return self.rpc.call_sync("goal/print", ) + + def loading_load(self, arg0: LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self.rpc.call_sync("loading/load", ) + + def loading_loadExample(self, arg0: str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadExample", ) + + def loading_loadKey(self, arg0: str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadKey", ) + + def loading_loadProblem(self, arg0: ProblemDefinition) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadProblem", ) + + def loading_loadTerm(self, arg0: str) -> ProofId: + """""" + + return self.rpc.call_sync("loading/loadTerm", ) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self.rpc.call_sync("meta/available_macros", ) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self.rpc.call_sync("meta/available_script_commands", ) + + def meta_version(self, ) -> str: + """""" + + return self.rpc.call_sync("meta/version", ) + + def proofTree_children(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/children", ) + + def proofTree_root(self, arg0: ProofId) -> TreeNodeDesc: + """""" + + return self.rpc.call_sync("proofTree/root", ) + + def proofTree_subtree(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self.rpc.call_sync("proofTree/subtree", ) + + def server_exit(self, ): + """""" + + return self.rpc.call_async("server/exit", ) + + def server_setTrace(self, arg0: SetTraceParams): + """""" + + return self.rpc.call_async("server/setTrace", ) + + def server_shutdown(self, ) -> bool: + """""" + + return self.rpc.call_sync("server/shutdown", ) + + +class Client(abc.ABCMeta): + @abstractmethod + def client_logTrace(self, arg0: LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, arg0: str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, arg0: ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, arg0: ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, arg0: ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass From 0efeaa2728d3456a84dae2c39763cdb4ddd481f4 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Wed, 1 Nov 2023 15:52:40 +0100 Subject: [PATCH 16/50] running for primitive data types, somethings wrong in de-/serialization --- api.meta.json | 445 +++++++++------ api.meta.md | 53 +- api.py | 374 ------------ keydata.py | 493 ++++++++++++++++ .../src/main/java/ExtractMetaData.java | 25 +- keyext.api.doc/src/main/java/Metamodel.java | 7 +- keyext.api.doc/src/main/java/PyGen.java | 136 ----- .../src/main/java/PythionGenerator.java | 223 ++++++++ keyext.api/build.gradle | 1 + .../keyproject/key/api/GenericSerializer.java | 56 ++ .../org/keyproject/key/api/KeyApiImpl.java | 3 +- .../org/keyproject/key/api/StartServer.java | 7 +- .../key/api/adapters/KeyAdapter.java | 2 +- .../ShowMessageRequestParams.java | 4 +- keyext.client.python/keyapi/__init__.py | 12 +- keyext.client.python/keyapi/keydata.py | 533 ++++++++++++++++++ keyext.client.python/keyapi/rpc.py | 58 +- keyext.client.python/keyapi/server.py | 161 ++++++ keyext.client.python/main.py | 22 +- keyext.client.python/rwtest.py | 402 ------------- server.py | 159 ++++++ 21 files changed, 2023 insertions(+), 1153 deletions(-) delete mode 100644 api.py create mode 100644 keydata.py delete mode 100644 keyext.api.doc/src/main/java/PyGen.java create mode 100644 keyext.api.doc/src/main/java/PythionGenerator.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java create mode 100644 keyext.client.python/keyapi/keydata.py create mode 100644 keyext.client.python/keyapi/server.py delete mode 100644 keyext.client.python/rwtest.py create mode 100644 server.py diff --git a/api.meta.json b/api.meta.json index 180b16a3019..953b76c6088 100644 --- a/api.meta.json +++ b/api.meta.json @@ -10,11 +10,13 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -51,19 +53,23 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "scriptCommandName", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -87,7 +93,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "SetTraceParams" } ] @@ -97,7 +103,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "ProofId" } ], @@ -112,11 +118,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "proof", "type": "ProofId" }, { - "name": "arg1", + "name": "nodeId", "type": "TreeNodeId" } ], @@ -134,11 +140,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "proof", "type": "ProofId" }, { - "name": "arg1", + "name": "nodeId", "type": "TreeNodeId" } ], @@ -156,11 +162,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "NodeId" }, { - "name": "arg1", + "name": "options", "type": "PrintOptions" } ], @@ -169,11 +175,13 @@ "fields": [ { "name": "id", - "type": "NodeTextId" + "type": "NodeTextId", + "documentation": "" }, { "name": "result", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -184,11 +192,11 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "NodeTextId" }, { - "name": "arg1", + "name": "pos", "type": "INT" } ], @@ -198,23 +206,28 @@ "fields": [ { "name": "commandId", - "type": "TermActionId" + "type": "TermActionId", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "kind", - "type": "TermActionKind" + "type": "TermActionKind", + "documentation": "" } ], "documentation": "" @@ -227,7 +240,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "TermActionId" } ], @@ -237,23 +250,28 @@ "fields": [ { "name": "commandId", - "type": "TermActionId" + "type": "TermActionId", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "kind", - "type": "TermActionKind" + "type": "TermActionKind", + "documentation": "" } ], "documentation": "" @@ -266,7 +284,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "NodeTextId" } ] @@ -276,7 +294,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "env", "type": "EnvironmentId" } ], @@ -286,31 +304,38 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "sort", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "retSort", - "type": "SortDesc" + "type": "SortDesc", + "documentation": "" }, { "name": "argSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "rigid", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "unique", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "skolemConstant", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -323,7 +348,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "env", "type": "EnvironmentId" } ], @@ -333,23 +358,28 @@ "fields": [ { "name": "string", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "documentation", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "extendsSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "anAbstract", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "s", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -362,7 +392,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "env", "type": "EnvironmentId" } ], @@ -372,27 +402,33 @@ "fields": [ { "name": "contractId", - "type": "ContractId" + "type": "ContractId", + "documentation": "" }, { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "typeName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "htmlText", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "plainText", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -405,7 +441,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "contractId", "type": "ContractId" } ], @@ -414,11 +450,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -429,7 +467,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "LoadParams" } ], @@ -439,7 +477,8 @@ "fields": [ { "name": "envId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -449,11 +488,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -462,11 +503,11 @@ } }, { - "name": "loading/loadKey", + "name": "loading/loadExample", "documentation": "", "args": [ { - "name": "arg0", + "name": "id", "type": "STRING" } ], @@ -475,23 +516,25 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" } }, { - "name": "loading/loadExample", + "name": "loading/loadProblem", "documentation": "", "args": [ { - "name": "arg0", - "type": "STRING" + "name": "problem", + "type": "ProblemDefinition" } ], "returnType": { @@ -499,23 +542,25 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" } }, { - "name": "loading/loadProblem", + "name": "loading/loadKey", "documentation": "", "args": [ { - "name": "arg0", - "type": "ProblemDefinition" + "name": "content", + "type": "STRING" } ], "returnType": { @@ -523,11 +568,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -538,7 +585,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "term", "type": "STRING" } ], @@ -547,11 +594,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -562,7 +611,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "e", "type": "STRING" } ] @@ -572,7 +621,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "LogTraceParams" } ] @@ -582,7 +631,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "ShowMessageParams" } ] @@ -592,7 +641,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "ShowMessageRequestParams" } ], @@ -601,7 +650,8 @@ "fields": [ { "name": "title", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -612,7 +662,7 @@ "documentation": "", "args": [ { - "name": "arg0", + "name": "params", "type": "ShowDocumentParams" } ], @@ -621,7 +671,8 @@ "fields": [ { "name": "success", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -634,11 +685,13 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -653,19 +706,23 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "scriptCommandName", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -684,7 +741,8 @@ "fields": [ { "name": "value", - "type": "TraceValue" + "type": "TraceValue", + "documentation": "" } ], "documentation": "" @@ -694,7 +752,8 @@ "fields": [ { "name": "envId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -704,11 +763,13 @@ "fields": [ { "name": "env", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "proofId", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -723,7 +784,8 @@ "fields": [ { "name": "id", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -733,11 +795,13 @@ "fields": [ { "name": "proofId", - "type": "ProofId" + "type": "ProofId", + "documentation": "" }, { "name": "nodeId", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -747,23 +811,28 @@ "fields": [ { "name": "unicode", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "width", - "type": "INT" + "type": "INT", + "documentation": "" }, { "name": "indentation", - "type": "INT" + "type": "INT", + "documentation": "" }, { "name": "pure", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "termLabels", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -773,11 +842,13 @@ "fields": [ { "name": "nodeId", - "type": "NodeId" + "type": "NodeId", + "documentation": "" }, { "name": "nodeTextId", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -787,11 +858,13 @@ "fields": [ { "name": "id", - "type": "NodeTextId" + "type": "NodeTextId", + "documentation": "" }, { "name": "result", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -801,15 +874,18 @@ "fields": [ { "name": "nodeId", - "type": "NodeId" + "type": "NodeId", + "documentation": "" }, { "name": "pio", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "id", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -829,23 +905,28 @@ "fields": [ { "name": "commandId", - "type": "TermActionId" + "type": "TermActionId", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "description", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "category", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "kind", - "type": "TermActionKind" + "type": "TermActionKind", + "documentation": "" } ], "documentation": "" @@ -860,23 +941,28 @@ "fields": [ { "name": "string", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "documentation", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "extendsSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "anAbstract", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "s", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -886,31 +972,38 @@ "fields": [ { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "sort", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "retSort", - "type": "SortDesc" + "type": "SortDesc", + "documentation": "" }, { "name": "argSorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "rigid", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "unique", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "skolemConstant", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" @@ -920,11 +1013,13 @@ "fields": [ { "name": "envId", - "type": "EnvironmentId" + "type": "EnvironmentId", + "documentation": "" }, { "name": "contractId", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -934,27 +1029,33 @@ "fields": [ { "name": "contractId", - "type": "ContractId" + "type": "ContractId", + "documentation": "" }, { "name": "name", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "displayName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "typeName", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "htmlText", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "plainText", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -964,23 +1065,28 @@ "fields": [ { "name": "keyFile", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "javaFile", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "classPath", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "bootClassPath", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "includes", - "type": "List" + "type": "List", + "documentation": "" } ], "documentation": "" @@ -990,23 +1096,28 @@ "fields": [ { "name": "sorts", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "functions", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "predicates", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "antecTerms", - "type": "List" + "type": "List", + "documentation": "" }, { "name": "succTerms", - "type": "List" + "type": "List", + "documentation": "" } ], "documentation": "" @@ -1016,11 +1127,13 @@ "fields": [ { "name": "messag", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "verbose", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -1042,34 +1155,34 @@ "fields": [ { "name": "type", - "type": "MessageType" + "type": "MessageType", + "documentation": "" }, { "name": "message", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" }, - { - "typeName": "MessageActionItem[]", - "fields": [], - "documentation": "" - }, { "typeName": "ShowMessageRequestParams", "fields": [ { "name": "type", - "type": "MessageType" + "type": "MessageType", + "documentation": "" }, { "name": "message", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "actions", - "type": "MessageActionItem[]" + "type": "List", + "documentation": "" } ], "documentation": "" @@ -1079,7 +1192,8 @@ "fields": [ { "name": "title", - "type": "STRING" + "type": "STRING", + "documentation": "" } ], "documentation": "" @@ -1089,11 +1203,13 @@ "fields": [ { "name": "start", - "type": "INT" + "type": "INT", + "documentation": "" }, { "name": "end", - "type": "INT" + "type": "INT", + "documentation": "" } ], "documentation": "" @@ -1103,19 +1219,23 @@ "fields": [ { "name": "uri", - "type": "STRING" + "type": "STRING", + "documentation": "" }, { "name": "external", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "takeFocus", - "type": "BOOL" + "type": "BOOL", + "documentation": "" }, { "name": "selection", - "type": "Range" + "type": "Range", + "documentation": "" } ], "documentation": "" @@ -1125,7 +1245,8 @@ "fields": [ { "name": "success", - "type": "BOOL" + "type": "BOOL", + "documentation": "" } ], "documentation": "" diff --git a/api.meta.md b/api.meta.md index f53d88619f3..f6d7a29c764 100644 --- a/api.meta.md +++ b/api.meta.md @@ -80,13 +80,6 @@ type MessageActionItem { } ``` -### Type: MessageActionItem[] -``` -type MessageActionItem[] { - -} -``` - ### Type: MessageType ``` enum MessageType { Unused, Error, Warning, Info, Log, Debug } @@ -206,7 +199,7 @@ type ShowMessageParams { ### Type: ShowMessageRequestParams ``` type ShowMessageRequestParams { - actions : MessageActionItem[] + actions : List message : STRING type : MessageType } @@ -285,63 +278,63 @@ type TreeNodeId { ### client/logTrace (`server ~~> client`) ``` -Client.client/logTrace( arg0 : LogTraceParams ) **async** +Client.client/logTrace( params : LogTraceParams ) **async** ``` ### client/sayHello (`server ~~> client`) ``` -Client.client/sayHello( arg0 : STRING ) **async** +Client.client/sayHello( e : STRING ) **async** ``` ### client/showDocument (`server -> client`) ``` -Client.client/showDocument( arg0 : ShowDocumentParams ) -> ShowDocumentResult +Client.client/showDocument( params : ShowDocumentParams ) -> ShowDocumentResult ``` ### client/sm (`server ~~> client`) ``` -Client.client/sm( arg0 : ShowMessageParams ) **async** +Client.client/sm( params : ShowMessageParams ) **async** ``` ### client/userResponse (`server -> client`) ``` -Client.client/userResponse( arg0 : ShowMessageRequestParams ) -> MessageActionItem +Client.client/userResponse( params : ShowMessageRequestParams ) -> MessageActionItem ``` ### env/contracts (`client -> server`) ``` -Server.env/contracts( arg0 : EnvironmentId ) -> ContractDesc[] +Server.env/contracts( env : EnvironmentId ) -> ContractDesc[] ``` ### env/functions (`client -> server`) ``` -Server.env/functions( arg0 : EnvironmentId ) -> FunctionDesc[] +Server.env/functions( env : EnvironmentId ) -> FunctionDesc[] ``` ### env/openContract (`client -> server`) ``` -Server.env/openContract( arg0 : ContractId ) -> ProofId +Server.env/openContract( contractId : ContractId ) -> ProofId ``` ### env/sorts (`client -> server`) ``` -Server.env/sorts( arg0 : EnvironmentId ) -> SortDesc[] +Server.env/sorts( env : EnvironmentId ) -> SortDesc[] ``` @@ -355,63 +348,63 @@ Server.examples/list( ) -> ExampleDesc[] ### goal/actions (`client -> server`) ``` -Server.goal/actions( arg0 : NodeTextId, arg1 : INT ) -> TermActionDesc[] +Server.goal/actions( id : NodeTextId, pos : INT ) -> TermActionDesc[] ``` ### goal/apply_action (`client -> server`) ``` -Server.goal/apply_action( arg0 : TermActionId ) -> TermActionDesc[] +Server.goal/apply_action( id : TermActionId ) -> TermActionDesc[] ``` ### goal/free (`client ~~> server`) ``` -Server.goal/free( arg0 : NodeTextId ) **async** +Server.goal/free( id : NodeTextId ) **async** ``` ### goal/print (`client -> server`) ``` -Server.goal/print( arg0 : NodeId, arg1 : PrintOptions ) -> NodeTextDesc +Server.goal/print( id : NodeId, options : PrintOptions ) -> NodeTextDesc ``` ### loading/load (`client -> server`) ``` -Server.loading/load( arg0 : LoadParams ) -> either +Server.loading/load( params : LoadParams ) -> either ``` ### loading/loadExample (`client -> server`) ``` -Server.loading/loadExample( arg0 : STRING ) -> ProofId +Server.loading/loadExample( id : STRING ) -> ProofId ``` ### loading/loadKey (`client -> server`) ``` -Server.loading/loadKey( arg0 : STRING ) -> ProofId +Server.loading/loadKey( content : STRING ) -> ProofId ``` ### loading/loadProblem (`client -> server`) ``` -Server.loading/loadProblem( arg0 : ProblemDefinition ) -> ProofId +Server.loading/loadProblem( problem : ProblemDefinition ) -> ProofId ``` ### loading/loadTerm (`client -> server`) ``` -Server.loading/loadTerm( arg0 : STRING ) -> ProofId +Server.loading/loadTerm( term : STRING ) -> ProofId ``` @@ -439,21 +432,21 @@ Server.meta/version( ) -> STRING ### proofTree/children (`client -> server`) ``` -Server.proofTree/children( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +Server.proofTree/children( proof : ProofId, nodeId : TreeNodeId ) -> TreeNodeDesc[] ``` ### proofTree/root (`client -> server`) ``` -Server.proofTree/root( arg0 : ProofId ) -> TreeNodeDesc +Server.proofTree/root( id : ProofId ) -> TreeNodeDesc ``` ### proofTree/subtree (`client -> server`) ``` -Server.proofTree/subtree( arg0 : ProofId, arg1 : TreeNodeId ) -> TreeNodeDesc[] +Server.proofTree/subtree( proof : ProofId, nodeId : TreeNodeId ) -> TreeNodeDesc[] ``` @@ -467,7 +460,7 @@ Server.server/exit( ) **async** ### server/setTrace (`client ~~> server`) ``` -Server.server/setTrace( arg0 : SetTraceParams ) **async** +Server.server/setTrace( params : SetTraceParams ) **async** ``` diff --git a/api.py b/api.py deleted file mode 100644 index c83050a763e..00000000000 --- a/api.py +++ /dev/null @@ -1,374 +0,0 @@ -import enum -import abc -import typing -class ExampleDesc: - """""" - - name : str - description : str - -class ProofScriptCommandDesc: - """""" - - -class ProofMacroDesc: - """""" - - name : str - category : str - description : str - scriptCommandName : str - -class TraceValue(enum.Enum): - """""" - - Off = None - Message = None - All = None - -class SetTraceParams: - """""" - - value : TraceValue - -class EnvironmentId: - """""" - - envId : str - -class ProofId: - """""" - - env : EnvironmentId - proofId : str - -class TreeNodeDesc: - """""" - - -class TreeNodeId: - """""" - - id : str - -class NodeId: - """""" - - proofId : ProofId - nodeId : int - -class PrintOptions: - """""" - - unicode : bool - width : int - indentation : int - pure : bool - termLabels : bool - -class NodeTextId: - """""" - - nodeId : NodeId - nodeTextId : int - -class NodeTextDesc: - """""" - - id : NodeTextId - result : str - -class TermActionId: - """""" - - nodeId : NodeId - pio : str - id : str - -class TermActionKind(enum.Enum): - """""" - - BuiltIn = None - Script = None - Macro = None - Taclet = None - -class TermActionDesc: - """""" - - commandId : TermActionId - displayName : str - description : str - category : str - kind : TermActionKind - -class List: - """""" - - -class SortDesc: - """""" - - string : str - documentation : str - extendsSorts : List - anAbstract : bool - s : str - -class FunctionDesc: - """""" - - name : str - sort : str - retSort : SortDesc - argSorts : List - rigid : bool - unique : bool - skolemConstant : bool - -class ContractId: - """""" - - envId : EnvironmentId - contractId : int - -class ContractDesc: - """""" - - contractId : ContractId - name : str - displayName : str - typeName : str - htmlText : str - plainText : str - -class LoadParams: - """""" - - keyFile : str - javaFile : str - classPath : List - bootClassPath : str - includes : List - -class ProblemDefinition: - """""" - - sorts : List - functions : List - predicates : List - antecTerms : List - succTerms : List - -class LogTraceParams: - """""" - - messag : str - verbose : str - -class MessageType(enum.Enum): - """""" - - Unused = None - Error = None - Warning = None - Info = None - Log = None - Debug = None - -class ShowMessageParams: - """""" - - type : MessageType - message : str - -class MessageActionItem[]: - """""" - - -class ShowMessageRequestParams: - """""" - - type : MessageType - message : str - actions : MessageActionItem[] - -class MessageActionItem: - """""" - - title : str - -class Range: - """""" - - start : int - end : int - -class ShowDocumentParams: - """""" - - uri : str - external : bool - takeFocus : bool - selection : Range - -class ShowDocumentResult: - """""" - - success : bool - -class TaskFinishedInfo: - """""" - - -class TaskStartedInfo: - """""" - - -class KeyServer(): - def env_contracts(self, arg0 : EnvironmentId) -> typing.List[ContractDesc]: - """""" - - return self.rpc.call_sync("env/contracts", ) - - def env_functions(self, arg0 : EnvironmentId) -> typing.List[FunctionDesc]: - """""" - - return self.rpc.call_sync("env/functions", ) - - def env_openContract(self, arg0 : ContractId) -> ProofId: - """""" - - return self.rpc.call_sync("env/openContract", ) - - def env_sorts(self, arg0 : EnvironmentId) -> typing.List[SortDesc]: - """""" - - return self.rpc.call_sync("env/sorts", ) - - def examples_list(self, ) -> typing.List[ExampleDesc]: - """""" - - return self.rpc.call_sync("examples/list", ) - - def goal_actions(self, arg0 : NodeTextId, arg1 : int) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/actions", ) - - def goal_apply_action(self, arg0 : TermActionId) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/apply_action", ) - - def goal_free(self, arg0 : NodeTextId): - """""" - - return self.rpc.call_async("goal/free", ) - - def goal_print(self, arg0 : NodeId, arg1 : PrintOptions) -> NodeTextDesc: - """""" - - return self.rpc.call_sync("goal/print", ) - - def loading_load(self, arg0 : LoadParams) -> typing.Union[EnvironmentId, ProofId]: - """""" - - return self.rpc.call_sync("loading/load", ) - - def loading_loadExample(self, arg0 : str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadExample", ) - - def loading_loadKey(self, arg0 : str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadKey", ) - - def loading_loadProblem(self, arg0 : ProblemDefinition) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadProblem", ) - - def loading_loadTerm(self, arg0 : str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadTerm", ) - - def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: - """""" - - return self.rpc.call_sync("meta/available_macros", ) - - def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: - """""" - - return self.rpc.call_sync("meta/available_script_commands", ) - - def meta_version(self, ) -> STRING: - """""" - - return self.rpc.call_sync("meta/version", ) - - def proofTree_children(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/children", ) - - def proofTree_root(self, arg0 : ProofId) -> TreeNodeDesc: - """""" - - return self.rpc.call_sync("proofTree/root", ) - - def proofTree_subtree(self, arg0 : ProofId, arg1 : TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/subtree", ) - - def server_exit(self, ): - """""" - - return self.rpc.call_async("server/exit", ) - - def server_setTrace(self, arg0 : SetTraceParams): - """""" - - return self.rpc.call_async("server/setTrace", ) - - def server_shutdown(self, ) -> BOOL: - """""" - - return self.rpc.call_sync("server/shutdown", ) - -class Client(abc.AbcMeta): - @abstractmethod - def client_logTrace(self, arg0 : LogTraceParams): - """""" - - pass - - @abstractmethod - def client_sayHello(self, arg0 : str): - """""" - - pass - - @abstractmethod - def client_showDocument(self, arg0 : ShowDocumentParams) -> ShowDocumentResult: - """""" - - pass - - @abstractmethod - def client_sm(self, arg0 : ShowMessageParams): - """""" - - pass - - @abstractmethod - def client_userResponse(self, arg0 : ShowMessageRequestParams) -> MessageActionItem: - """""" - - pass - diff --git a/keydata.py b/keydata.py new file mode 100644 index 00000000000..59511c2a7a8 --- /dev/null +++ b/keydata.py @@ -0,0 +1,493 @@ +from __future__ import annotations +import enum +import abc +import typing +from abc import abstractmethod, ABCMeta + +class ExampleDesc: + """""" + + name : str + """""" + + description : str + """""" + + def __init__(self, name, description): + self.name = name + self.description = description + +class ProofScriptCommandDesc: + """""" + + def __init__(self, ): + pass + + +class ProofMacroDesc: + """""" + + name : str + """""" + + category : str + """""" + + description : str + """""" + + scriptCommandName : str + """""" + + def __init__(self, name, category, description, scriptCommandName): + self.name = name + self.category = category + self.description = description + self.scriptCommandName = scriptCommandName + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + +class SetTraceParams: + """""" + + value : TraceValue + """""" + + def __init__(self, value): + self.value = value + +class EnvironmentId: + """""" + + envId : str + """""" + + def __init__(self, envId): + self.envId = envId + +class ProofId: + """""" + + env : EnvironmentId + """""" + + proofId : str + """""" + + def __init__(self, env, proofId): + self.env = env + self.proofId = proofId + +class TreeNodeDesc: + """""" + + def __init__(self, ): + pass + + +class TreeNodeId: + """""" + + id : str + """""" + + def __init__(self, id): + self.id = id + +class NodeId: + """""" + + proofId : ProofId + """""" + + nodeId : int + """""" + + def __init__(self, proofId, nodeId): + self.proofId = proofId + self.nodeId = nodeId + +class PrintOptions: + """""" + + unicode : bool + """""" + + width : int + """""" + + indentation : int + """""" + + pure : bool + """""" + + termLabels : bool + """""" + + def __init__(self, unicode, width, indentation, pure, termLabels): + self.unicode = unicode + self.width = width + self.indentation = indentation + self.pure = pure + self.termLabels = termLabels + +class NodeTextId: + """""" + + nodeId : NodeId + """""" + + nodeTextId : int + """""" + + def __init__(self, nodeId, nodeTextId): + self.nodeId = nodeId + self.nodeTextId = nodeTextId + +class NodeTextDesc: + """""" + + id : NodeTextId + """""" + + result : str + """""" + + def __init__(self, id, result): + self.id = id + self.result = result + +class TermActionId: + """""" + + nodeId : NodeId + """""" + + pio : str + """""" + + id : str + """""" + + def __init__(self, nodeId, pio, id): + self.nodeId = nodeId + self.pio = pio + self.id = id + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + +class TermActionDesc: + """""" + + commandId : TermActionId + """""" + + displayName : str + """""" + + description : str + """""" + + category : str + """""" + + kind : TermActionKind + """""" + + def __init__(self, commandId, displayName, description, category, kind): + self.commandId = commandId + self.displayName = displayName + self.description = description + self.category = category + self.kind = kind + +class List: + """""" + + def __init__(self, ): + pass + + +class SortDesc: + """""" + + string : str + """""" + + documentation : str + """""" + + extendsSorts : List + """""" + + anAbstract : bool + """""" + + s : str + """""" + + def __init__(self, string, documentation, extendsSorts, anAbstract, s): + self.string = string + self.documentation = documentation + self.extendsSorts = extendsSorts + self.anAbstract = anAbstract + self.s = s + +class FunctionDesc: + """""" + + name : str + """""" + + sort : str + """""" + + retSort : SortDesc + """""" + + argSorts : List + """""" + + rigid : bool + """""" + + unique : bool + """""" + + skolemConstant : bool + """""" + + def __init__(self, name, sort, retSort, argSorts, rigid, unique, skolemConstant): + self.name = name + self.sort = sort + self.retSort = retSort + self.argSorts = argSorts + self.rigid = rigid + self.unique = unique + self.skolemConstant = skolemConstant + +class ContractId: + """""" + + envId : EnvironmentId + """""" + + contractId : int + """""" + + def __init__(self, envId, contractId): + self.envId = envId + self.contractId = contractId + +class ContractDesc: + """""" + + contractId : ContractId + """""" + + name : str + """""" + + displayName : str + """""" + + typeName : str + """""" + + htmlText : str + """""" + + plainText : str + """""" + + def __init__(self, contractId, name, displayName, typeName, htmlText, plainText): + self.contractId = contractId + self.name = name + self.displayName = displayName + self.typeName = typeName + self.htmlText = htmlText + self.plainText = plainText + +class LoadParams: + """""" + + keyFile : str + """""" + + javaFile : str + """""" + + classPath : List + """""" + + bootClassPath : str + """""" + + includes : List + """""" + + def __init__(self, keyFile, javaFile, classPath, bootClassPath, includes): + self.keyFile = keyFile + self.javaFile = javaFile + self.classPath = classPath + self.bootClassPath = bootClassPath + self.includes = includes + +class ProblemDefinition: + """""" + + sorts : List + """""" + + functions : List + """""" + + predicates : List + """""" + + antecTerms : List + """""" + + succTerms : List + """""" + + def __init__(self, sorts, functions, predicates, antecTerms, succTerms): + self.sorts = sorts + self.functions = functions + self.predicates = predicates + self.antecTerms = antecTerms + self.succTerms = succTerms + +class LogTraceParams: + """""" + + messag : str + """""" + + verbose : str + """""" + + def __init__(self, messag, verbose): + self.messag = messag + self.verbose = verbose + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + +class ShowMessageParams: + """""" + + type : MessageType + """""" + + message : str + """""" + + def __init__(self, type, message): + self.type = type + self.message = message + +class ShowMessageRequestParams: + """""" + + type : MessageType + """""" + + message : str + """""" + + actions : List + """""" + + def __init__(self, type, message, actions): + self.type = type + self.message = message + self.actions = actions + +class MessageActionItem: + """""" + + title : str + """""" + + def __init__(self, title): + self.title = title + +class Range: + """""" + + start : int + """""" + + end : int + """""" + + def __init__(self, start, end): + self.start = start + self.end = end + +class ShowDocumentParams: + """""" + + uri : str + """""" + + external : bool + """""" + + takeFocus : bool + """""" + + selection : Range + """""" + + def __init__(self, uri, external, takeFocus, selection): + self.uri = uri + self.external = external + self.takeFocus = takeFocus + self.selection = selection + +class ShowDocumentResult: + """""" + + success : bool + """""" + + def __init__(self, success): + self.success = success + +class TaskFinishedInfo: + """""" + + def __init__(self, ): + pass + + +class TaskStartedInfo: + """""" + + def __init__(self, ): + pass + + +KEY_DATA_CLASSES = { "ExampleDesc": ExampleDesc,"ProofScriptCommandDesc": ProofScriptCommandDesc,"ProofMacroDesc": ProofMacroDesc,"TraceValue": TraceValue,"SetTraceParams": SetTraceParams,"EnvironmentId": EnvironmentId,"ProofId": ProofId,"TreeNodeDesc": TreeNodeDesc,"TreeNodeId": TreeNodeId,"NodeId": NodeId,"PrintOptions": PrintOptions,"NodeTextId": NodeTextId,"NodeTextDesc": NodeTextDesc,"TermActionId": TermActionId,"TermActionKind": TermActionKind,"TermActionDesc": TermActionDesc,"List": List,"SortDesc": SortDesc,"FunctionDesc": FunctionDesc,"ContractId": ContractId,"ContractDesc": ContractDesc,"LoadParams": LoadParams,"ProblemDefinition": ProblemDefinition,"LogTraceParams": LogTraceParams,"MessageType": MessageType,"ShowMessageParams": ShowMessageParams,"ShowMessageRequestParams": ShowMessageRequestParams,"MessageActionItem": MessageActionItem,"Range": Range,"ShowDocumentParams": ShowDocumentParams,"ShowDocumentResult": ShowDocumentResult,"TaskFinishedInfo": TaskFinishedInfo,"TaskStartedInfo": TaskStartedInfo } + diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java index 2855e390f75..1c6c904553e 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -22,6 +22,8 @@ import java.nio.file.Paths; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; /** * @author Alexander Weigl @@ -43,21 +45,16 @@ public static void main(String[] args) { addClientEndpoint(method); } - try { - Files.writeString(Paths.get("api.meta.json"), getGson().toJson(keyApi)); - } catch (IOException e) { - e.printStackTrace(); - } + runGenerator("api.meta.json", (a) -> () -> getGson().toJson(a)); + runGenerator("api.meta.md", DocGen::new); + runGenerator("keydata.py", PythionGenerator.PyDataGen::new); + runGenerator("server.py", PythionGenerator.PyApiGen::new); + } + private static void runGenerator(String target, Function> api) { try { - var n = new DocGen(keyApi); - Files.writeString(Paths.get("api.meta.md"), n.get()); - } catch (IOException e) { - e.printStackTrace(); - } - try { - var n = new PyGen(keyApi); - Files.writeString(Paths.get("api.py"), n.get()); + var n = api.apply(keyApi); + Files.writeString(Paths.get(target), n.get()); } catch (IOException e) { e.printStackTrace(); } @@ -124,7 +121,7 @@ private static List translate(Parameter[] parameters) { } private static Metamodel.Argument translate(Parameter parameter) { - var type = getOrFindType(parameter.getType()).name(); + var type = getOrFindType(parameter.getType()).name(); return new Metamodel.Argument(parameter.getName(), type); } diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/Metamodel.java index 833699cfe0c..1a868f49a06 100644 --- a/keyext.api.doc/src/main/java/Metamodel.java +++ b/keyext.api.doc/src/main/java/Metamodel.java @@ -41,10 +41,13 @@ record ClientRequest(String name, String documentation, List args, Typ record ClientNotification(String name, String documentation, List args) implements Endpoint { } - record Field(String name, /*Type*/ String type) { + record Field(String name, /*Type*/ String type, String documentation) { + Field(String name, String type) { + this(name, type, ""); + } } - sealed interface Type { + public sealed interface Type { default String kind() { return getClass().getSimpleName(); } diff --git a/keyext.api.doc/src/main/java/PyGen.java b/keyext.api.doc/src/main/java/PyGen.java deleted file mode 100644 index 357c2f51e8d..00000000000 --- a/keyext.api.doc/src/main/java/PyGen.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Comparator; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public class PyGen implements Supplier { - private final Metamodel.KeyApi metamodel; - private PrintWriter out; - private final StringWriter target = new StringWriter(); - - public PyGen(Metamodel.KeyApi metamodel) { - this.metamodel = metamodel; - } - - @Override - public String get() { - try (var out = new PrintWriter(target)) { - this.out = out; - - out.format(""" - import enum - import abc - import typing - from abc import abstractmethod - """); - - metamodel.types().forEach(this::printType); - server( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); - - client( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); - - } - return target.toString(); - } - - private void client(Stream sorted) { - out.format("class Client(abc.AbcMeta):%n"); - sorted.forEach(this::clientEndpoint); - } - - private void clientEndpoint(Metamodel.Endpoint endpoint) { - var args = endpoint.args().stream() - .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) - .collect(Collectors.joining(", ")); - out.format(" @abstractmethod%n"); - if (endpoint instanceof Metamodel.ClientRequest sr) { - out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, asPython(sr.returnType())); - } else { - out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); - } - out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" pass".formatted(endpoint.name(), "")); - out.println(); - out.println(); - } - - private void server(Stream sorted) { - out.format("class KeyServer():%n"); - sorted.forEach(this::serverEndpoint); - } - - private void serverEndpoint(Metamodel.Endpoint endpoint) { - var args = endpoint.args().stream() - .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) - .collect(Collectors.joining(", ")); - if (endpoint instanceof Metamodel.ServerRequest sr) { - out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, - asPython(sr.returnType())); - out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); - out.format(" return self.rpc.call_sync(\"%s\", %s)".formatted(endpoint.name(), "")); - } else { - out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); - out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" return self.rpc.call_async(\"%s\", %s)".formatted(endpoint.name(), "")); - } - out.println(); - out.println(); - } - - private void printType(Metamodel.Type type) { - if (type instanceof Metamodel.ObjectType ot) { - out.format("class %s:%n".formatted(type.name())); - out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); - ot.fields().forEach(it -> out.format(" %s : %s%n".formatted(it.name(), asPython(it.type())))); - } else if (type instanceof Metamodel.EnumType et) { - out.format("class %s(enum.Enum):%n".formatted(type.name())); - out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); - et.values().forEach(it -> out.format(" %s = None%n".formatted(it))); - } - out.println(); - } - - private String asPython(String typeName) { - return switch (typeName) { - case "INT" -> "int"; - case "LONG" -> "int"; - case "STRING" -> "str"; - case "BOOL" -> "bool"; - case "DOUBLE" -> "float"; - default -> { - var t = findType(typeName); - yield asPython(t); - } - }; - } - - private String asPython(Metamodel.Type t) { - if (t instanceof Metamodel.ListType lt) { - return "typing.List[" + asPython(lt.type()) + "]"; - } - - if (t instanceof Metamodel.EitherType lt) { - return "typing.Union[" + asPython(lt.a()) + ", " + asPython(lt.b()) + "]"; - } - return t.name(); - } - - private Metamodel.Type findType(String typeName) { - return this.metamodel.types().stream().filter(it -> it.name().equals(typeName)).findFirst() - .orElseThrow(() -> new RuntimeException("Could not find type: " + typeName)); - } -} \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/PythionGenerator.java b/keyext.api.doc/src/main/java/PythionGenerator.java new file mode 100644 index 00000000000..a4d2018c328 --- /dev/null +++ b/keyext.api.doc/src/main/java/PythionGenerator.java @@ -0,0 +1,223 @@ +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public abstract class PythionGenerator implements Supplier { + protected final Metamodel.KeyApi metamodel; + protected PrintWriter out; + protected final StringWriter target = new StringWriter(); + + public PythionGenerator(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + run(); + } + return target.toString(); + } + + protected abstract void run(); + + protected String asPython(String typeName) { + return switch (typeName) { + case "INT" -> "int"; + case "LONG" -> "int"; + case "STRING" -> "str"; + case "BOOL" -> "bool"; + case "DOUBLE" -> "float"; + default -> { + var t = findType(typeName); + yield asPython(t); + } + }; + } + + protected String asPython(Metamodel.Type t) { + if (t instanceof Metamodel.ListType lt) { + return "typing.List[" + asPython(lt.type()) + "]"; + } + + if (t instanceof Metamodel.EitherType lt) { + return "typing.Union[" + asPython(lt.a()) + ", " + asPython(lt.b()) + "]"; + } + + if (t instanceof Metamodel.BuiltinType bt) { + return switch (bt) { + case INT -> "int"; + case LONG -> "int"; + case STRING -> "str"; + case BOOL -> "bool"; + case DOUBLE -> "float"; + }; + } + return t.name(); + } + + protected Metamodel.Type findType(String typeName) { + return this.metamodel.types().stream().filter(it -> it.name().equals(typeName)).findFirst() + .orElseThrow(() -> new RuntimeException("Could not find type: " + typeName)); + } + + + public static class PyApiGen extends PythionGenerator { + public PyApiGen(Metamodel.KeyApi metamodel) { + super(metamodel); + } + + @Override + protected void run() { + out.format(""" + from __future__ import annotations + from .keydata import * + from .rpc import ServerBase, LspEndpoint + + import enum + import abc + import typing + from abc import abstractmethod + """); + server( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + + client( + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + } + + + private void client(Stream sorted) { + out.format("class Client(abc.ABCMeta):%n"); + sorted.forEach(this::clientEndpoint); + } + + private void clientEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + out.format(" @abstractmethod%n"); + if (endpoint instanceof Metamodel.ClientRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, + asPython(sr.returnType())); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + } + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" pass".formatted(endpoint.name(), "")); + out.println(); + out.println(); + } + + private void server(Stream sorted) { + out.format(""" + class KeyServer(ServerBase):%n + def __init__(self, endpoint : LspEndpoint): + super().__init__(endpoint) + + """); + sorted.forEach(this::serverEndpoint); + } + + private void serverEndpoint(Metamodel.Endpoint endpoint) { + var args = endpoint.args().stream() + .map(it -> "%s : %s".formatted(it.name(), asPython(it.type()))) + .collect(Collectors.joining(", ")); + + var params = "[]"; + if (!endpoint.args().isEmpty()) { + params = endpoint.args().stream() + .map(Metamodel.Argument::name) + .collect(Collectors.joining(" , ", "[", "]")); + } + + if (endpoint instanceof Metamodel.ServerRequest sr) { + out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, + asPython(sr.returnType())); + out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); + out.format(" return self._call_sync(\"%s\", %s)".formatted(endpoint.name(), params)); + } else { + out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); + out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); + out.format(" return self._call_async(\"%s\", %s)".formatted(endpoint.name(), params)); + } + out.println(); + out.println(); + } + + } + + + public static class PyDataGen extends PythionGenerator { + public PyDataGen(Metamodel.KeyApi metamodel) { + super(metamodel); + } + + @Override + public String get() { + try (var out = new PrintWriter(target)) { + this.out = out; + run(); + } + return target.toString(); + } + + protected void run() { + out.format(""" + from __future__ import annotations + import enum + import abc + import typing + from abc import abstractmethod, ABCMeta + + """); + metamodel.types().forEach(this::printType); + + var names = metamodel.types().stream().map(it -> "\"%s\": %s".formatted(it.name(), it.name())) + .collect(Collectors.joining(",")); + out.format("KEY_DATA_CLASSES = { %s }%n%n", names); + } + + private void printType(Metamodel.Type type) { + if (type instanceof Metamodel.ObjectType ot) { + out.format("class %s:%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n", type.documentation()); + ot.fields().forEach(it -> out.format("%n %s : %s%n \"\"\"%s\"\"\"%n" + .formatted(it.name(), asPython(it.type()), it.documentation()))); + + out.format("\n def __init__(self%s):%n".formatted( + ot.fields().stream() + .map(Metamodel.Field::name) + .collect(Collectors.joining(", ", ", ", "")) + )); + + if (ot.fields().isEmpty()) + out.format(" pass%n%n"); + + for (Metamodel.Field field : ot.fields()) { + out.format(" self.%s = %s%n", field.name(), field.name()); + } + + } else if (type instanceof Metamodel.EnumType et) { + out.format("class %s(enum.Enum):%n".formatted(type.name())); + out.format(" \"\"\"%s\"\"\"%n%n", type.documentation()); + et.values().forEach(it -> out.format(" %s = None%n".formatted(it))); + } + out.println(); + } + } +} \ No newline at end of file diff --git a/keyext.api/build.gradle b/keyext.api/build.gradle index fbbbac93898..71e79884c3d 100644 --- a/keyext.api/build.gradle +++ b/keyext.api/build.gradle @@ -27,5 +27,6 @@ dependencies { compileJava { // for GraalVM options.compilerArgs += ["-Aproject=${project.group}/${project.name}"] + options.compilerArgs += ["-parameters"] // for having parameter name in reflection } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java new file mode 100644 index 00000000000..b8f61b62272 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java @@ -0,0 +1,56 @@ +package org.keyproject.key.api; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +/** + * Stackoverflow post + */ +public class GenericSerializer implements JsonSerializer /*, JsonDeserializer*/ { + + private static final String CLASS_PROPERTY_NAME = "$type"; + private final Gson gson; + + public GenericSerializer() { + gson = new Gson(); + } + + public GenericSerializer(Gson gson) { + this.gson = gson; + } + + /* + @Override + public Object deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + + Class actualClass; + if (json.isJsonObject()) { + JsonObject jsonObject = json.getAsJsonObject(); + String className = jsonObject.get(CLASS_PROPERTY_NAME).getAsString(); + try { + actualClass = Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new JsonParseException(e.getMessage()); + } + } else { + actualClass = typeOfT.getClass(); + } + + return gson.fromJson(json, actualClass); + } + */ + + @Override + public JsonElement serialize(Object src, Type typeOfSrc, + JsonSerializationContext context) { + JsonElement retValue = gson.toJsonTree(src); + if (retValue.isJsonObject()) { + retValue.getAsJsonObject().addProperty(CLASS_PROPERTY_NAME, src.getClass().getName()); + } + return retValue; + } + +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index 7ff86ae2c09..f2a28731d3a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -75,7 +75,8 @@ public KeyApiImpl() { @JsonRequest public CompletableFuture> examples() { return CompletableFutures.computeAsync((c) -> - ExampleChooser.listExamples(ExampleChooser.lookForExamples()).stream().map(it -> ExampleDesc.from(it)).toList()); + ExampleChooser.listExamples(ExampleChooser.lookForExamples()) + .stream().map(ExampleDesc::from).toList()); } @Override diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index b95ae6eebe2..26981875aef 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -26,8 +26,6 @@ public class StartServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); - private static KeyAdapter adapter; - //region CLI arguments @Option(names = "--std", description = "use stdout and stdin for communication") boolean stdStreams; @@ -146,7 +144,9 @@ public void run() { public static void configureJson(GsonBuilder gsonBuilder) { - adapter = new KeyAdapter(gsonBuilder); + gsonBuilder.registerTypeHierarchyAdapter(Object.class, new GenericSerializer()); + gsonBuilder.registerTypeAdapter(File.class, new KeyAdapter.FileTypeAdapter()); + } public static Launcher launch(OutputStream out, InputStream in, KeyApiImpl keyApi) { @@ -167,3 +167,4 @@ public static Launcher launch(OutputStream out, InputStream in, KeyAp return launcherBuilder.create(); } } + diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 68b330491fc..c17647c9e4f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -48,7 +48,7 @@ public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationCo } } - static class FileTypeAdapter extends TypeAdapter { + public static class FileTypeAdapter extends TypeAdapter { @Override public void write(JsonWriter out, File value) throws IOException { out.value(value.toString()); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java index 5e5f4f1410b..49e662c6524 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java @@ -1,5 +1,7 @@ package org.keyproject.key.api.remoteclient; +import java.util.List; + public record ShowMessageRequestParams( /** * The message type. See {@link MessageType} @@ -15,6 +17,6 @@ public record ShowMessageRequestParams( * The message action items to present. * */ - MessageActionItem[] actions + List actions ) { } \ No newline at end of file diff --git a/keyext.client.python/keyapi/__init__.py b/keyext.client.python/keyapi/__init__.py index 4a913b39b2e..4807ec5ee59 100644 --- a/keyext.client.python/keyapi/__init__.py +++ b/keyext.client.python/keyapi/__init__.py @@ -1,8 +1,8 @@ -from keyapi.rpc import * +import abc +from abc import abstractmethod, ABCMeta + +from keyapi.keydata import * +from keyapi.rpc import LspEndpoint + -class KeyStub(JsonRPCHandler): - def __init__(self, input, output): - super().__init__(input, output) - def list_examples(self): - return self._send("examples/list", []) diff --git a/keyext.client.python/keyapi/keydata.py b/keyext.client.python/keyapi/keydata.py new file mode 100644 index 00000000000..dfeaf76f7c7 --- /dev/null +++ b/keyext.client.python/keyapi/keydata.py @@ -0,0 +1,533 @@ +from __future__ import annotations +import enum +import abc +import typing +from abc import abstractmethod, ABCMeta + + +class ExampleDesc: + """""" + + name: str + """""" + + description: str + """""" + + def __init__(self, name, description): + self.name = name + self.description = description + + +class ProofScriptCommandDesc: + """""" + + def __init__(self, ): + pass + + +class ProofMacroDesc: + """""" + + name: str + """""" + + category: str + """""" + + description: str + """""" + + scriptCommandName: str + """""" + + def __init__(self, name, category, description, scriptCommandName): + self.name = name + self.category = category + self.description = description + self.scriptCommandName = scriptCommandName + + +class TraceValue(enum.Enum): + """""" + + Off = None + Message = None + All = None + + +class SetTraceParams: + """""" + + value: TraceValue + """""" + + def __init__(self, value): + self.value = value + + +class EnvironmentId: + """""" + + envId: str + """""" + + def __init__(self, envId): + self.envId = envId + + +class ProofId: + """""" + + env: EnvironmentId + """""" + + proofId: str + """""" + + def __init__(self, env, proofId): + self.env = env + self.proofId = proofId + + +class TreeNodeDesc: + """""" + + def __init__(self, ): + pass + + +class TreeNodeId: + """""" + + id: str + """""" + + def __init__(self, id): + self.id = id + + +class NodeId: + """""" + + proofId: ProofId + """""" + + nodeId: int + """""" + + def __init__(self, proofId, nodeId): + self.proofId = proofId + self.nodeId = nodeId + + +class PrintOptions: + """""" + + unicode: bool + """""" + + width: int + """""" + + indentation: int + """""" + + pure: bool + """""" + + termLabels: bool + """""" + + def __init__(self, unicode, width, indentation, pure, termLabels): + self.unicode = unicode + self.width = width + self.indentation = indentation + self.pure = pure + self.termLabels = termLabels + + +class NodeTextId: + """""" + + nodeId: NodeId + """""" + + nodeTextId: int + """""" + + def __init__(self, nodeId, nodeTextId): + self.nodeId = nodeId + self.nodeTextId = nodeTextId + + +class NodeTextDesc: + """""" + + id: NodeTextId + """""" + + result: str + """""" + + def __init__(self, id, result): + self.id = id + self.result = result + + +class TermActionId: + """""" + + nodeId: NodeId + """""" + + pio: str + """""" + + id: str + """""" + + def __init__(self, nodeId, pio, id): + self.nodeId = nodeId + self.pio = pio + self.id = id + + +class TermActionKind(enum.Enum): + """""" + + BuiltIn = None + Script = None + Macro = None + Taclet = None + + +class TermActionDesc: + """""" + + commandId: TermActionId + """""" + + displayName: str + """""" + + description: str + """""" + + category: str + """""" + + kind: TermActionKind + """""" + + def __init__(self, commandId, displayName, description, category, kind): + self.commandId = commandId + self.displayName = displayName + self.description = description + self.category = category + self.kind = kind + + +class List: + """""" + + def __init__(self, ): + pass + + +class SortDesc: + """""" + + string: str + """""" + + documentation: str + """""" + + extendsSorts: List + """""" + + anAbstract: bool + """""" + + s: str + """""" + + def __init__(self, string, documentation, extendsSorts, anAbstract, s): + self.string = string + self.documentation = documentation + self.extendsSorts = extendsSorts + self.anAbstract = anAbstract + self.s = s + + +class FunctionDesc: + """""" + + name: str + """""" + + sort: str + """""" + + retSort: SortDesc + """""" + + argSorts: List + """""" + + rigid: bool + """""" + + unique: bool + """""" + + skolemConstant: bool + """""" + + def __init__(self, name, sort, retSort, argSorts, rigid, unique, skolemConstant): + self.name = name + self.sort = sort + self.retSort = retSort + self.argSorts = argSorts + self.rigid = rigid + self.unique = unique + self.skolemConstant = skolemConstant + + +class ContractId: + """""" + + envId: EnvironmentId + """""" + + contractId: int + """""" + + def __init__(self, envId, contractId): + self.envId = envId + self.contractId = contractId + + +class ContractDesc: + """""" + + contractId: ContractId + """""" + + name: str + """""" + + displayName: str + """""" + + typeName: str + """""" + + htmlText: str + """""" + + plainText: str + """""" + + def __init__(self, contractId, name, displayName, typeName, htmlText, plainText): + self.contractId = contractId + self.name = name + self.displayName = displayName + self.typeName = typeName + self.htmlText = htmlText + self.plainText = plainText + + +class LoadParams: + """""" + + keyFile: str + """""" + + javaFile: str + """""" + + classPath: List + """""" + + bootClassPath: str + """""" + + includes: List + """""" + + def __init__(self, keyFile, javaFile, classPath, bootClassPath, includes): + self.keyFile = keyFile + self.javaFile = javaFile + self.classPath = classPath + self.bootClassPath = bootClassPath + self.includes = includes + + + +class ProblemDefinition: + """""" + + sorts: List + """""" + + functions: List + """""" + + predicates: List + """""" + + antecTerms: List + """""" + + succTerms: List + """""" + + def __init__(self, sorts, functions, predicates, antecTerms, succTerms): + self.sorts = sorts + self.functions = functions + self.predicates = predicates + self.antecTerms = antecTerms + self.succTerms = succTerms + + +class LogTraceParams: + """""" + + messag: str + """""" + + verbose: str + """""" + + def __init__(self, messag, verbose): + self.messag = messag + self.verbose = verbose + + +class MessageType(enum.Enum): + """""" + + Unused = None + Error = None + Warning = None + Info = None + Log = None + Debug = None + + +class ShowMessageParams: + """""" + + type: MessageType + """""" + + message: str + """""" + + def __init__(self, type, message): + self.type = type + self.message = message + + +class ShowMessageRequestParams: + """""" + + type: MessageType + """""" + + message: str + """""" + + actions: List + """""" + + def __init__(self, type, message, actions): + self.type = type + self.message = message + self.actions = actions + + +class MessageActionItem: + """""" + + title: str + """""" + + def __init__(self, title): + self.title = title + + +class Range: + """""" + + start: int + """""" + + end: int + """""" + + def __init__(self, start, end): + self.start = start + self.end = end + + +class ShowDocumentParams: + """""" + + uri: str + """""" + + external: bool + """""" + + takeFocus: bool + """""" + + selection: Range + """""" + + def __init__(self, uri, external, takeFocus, selection): + self.uri = uri + self.external = external + self.takeFocus = takeFocus + self.selection = selection + + +class ShowDocumentResult: + """""" + + success: bool + """""" + + def __init__(self, success): + self.success = success + + +class TaskFinishedInfo: + """""" + + def __init__(self, ): + pass + + +class TaskStartedInfo: + """""" + + def __init__(self, ): + pass + + +KEY_DATA_CLASSES = {"ExampleDesc": ExampleDesc, "ProofScriptCommandDesc": ProofScriptCommandDesc, + "ProofMacroDesc": ProofMacroDesc, "TraceValue": TraceValue, "SetTraceParams": SetTraceParams, + "EnvironmentId": EnvironmentId, "ProofId": ProofId, "TreeNodeDesc": TreeNodeDesc, + "TreeNodeId": TreeNodeId, "NodeId": NodeId, "PrintOptions": PrintOptions, "NodeTextId": NodeTextId, + "NodeTextDesc": NodeTextDesc, "TermActionId": TermActionId, "TermActionKind": TermActionKind, + "TermActionDesc": TermActionDesc, "List": List, "SortDesc": SortDesc, "FunctionDesc": FunctionDesc, + "ContractId": ContractId, "ContractDesc": ContractDesc, "LoadParams": LoadParams, + "ProblemDefinition": ProblemDefinition, "LogTraceParams": LogTraceParams, + "MessageType": MessageType, "ShowMessageParams": ShowMessageParams, + "ShowMessageRequestParams": ShowMessageRequestParams, "MessageActionItem": MessageActionItem, + "Range": Range, "ShowDocumentParams": ShowDocumentParams, "ShowDocumentResult": ShowDocumentResult, + "TaskFinishedInfo": TaskFinishedInfo, "TaskStartedInfo": TaskStartedInfo} diff --git a/keyext.client.python/keyapi/rpc.py b/keyext.client.python/keyapi/rpc.py index 02ba2be474b..c112055e006 100644 --- a/keyext.client.python/keyapi/rpc.py +++ b/keyext.client.python/keyapi/rpc.py @@ -1,10 +1,11 @@ import enum import json -import sys import threading -from io import TextIOWrapper +import typing from typing import Dict +from keyapi import KEY_DATA_CLASSES + JSON_RPC_REQ_FORMAT = "Content-Length: {json_string_len}\r\n\r\n{json_string}" LEN_HEADER = "Content-Length: " TYPE_HEADER = "Content-Type: " @@ -16,16 +17,20 @@ class MyEncoder(json.JSONEncoder): """ def default(self, o): # pylint: disable=E0202 - return o.__dict__ + d = dict(o.__dict__) + d['$type'] = type(o).__name__ + return d class ResponseError(Exception): - def __init__(self, error_code, message): + def __init__(self, error_code, message, data=None): super().__init__(message) self.error_code = error_code + self.data = data class ErrorCodes(enum.Enum): + MethodNotFound = None ParseError = 1 @@ -57,27 +62,27 @@ def send_request(self, message): :param dict message: The message to send. ''' - json_string = json.dumps(message, cls=MyEncoder) + json_string = json.dumps(message , cls=MyEncoder) jsonrpc_req = self.__add_header(json_string) with self.write_lock: - self.stdin.write(jsonrpc_req.encode()) - self.stdin.flush() + self.stdout.write(jsonrpc_req) + self.stdout.flush() - def recv_response(self): + def recv_response(self) -> object: ''' Recives a message. :return: a message ''' - with self.read_lock: + with (self.read_lock): message_size = None while True: # read header - line = self.stdout.readline() + line = self.stdin.readline() if not line: # server quit return None - line = line.decode("utf-8") + # line = line.decode("utf-8") if not line.endswith("\r\n"): raise ResponseError(ErrorCodes.ParseError, "Bad header: missing newline") # remove the "\r\n" @@ -99,12 +104,18 @@ def recv_response(self): if not message_size: raise ResponseError(ErrorCodes.ParseError, "Bad header: missing size") - jsonrpc_res = self.stdout.read(message_size).decode("utf-8") - return json.loads(jsonrpc_res) + jsonrpc_res = self.stdin.read(message_size) # .decode("utf-8") + return json.loads(jsonrpc_res, object_hook=object_decoder) + + +def object_decoder(obj): + if '$type' in obj: + return KEY_DATA_CLASSES[obj["$type"]](**obj) + return obj class LspEndpoint(threading.Thread): - def __init__(self, json_rpc_endpoint: JsonRpcEndpoint, method_callbacks=None, notify_callbacks=None, timeout=2): + def __init__(self, json_rpc_endpoint: JsonRpcEndpoint, method_callbacks=None, notify_callbacks=None, timeout=2000): super().__init__() self.json_rpc_endpoint: JsonRpcEndpoint = json_rpc_endpoint self.notify_callbacks: Dict = notify_callbacks or {} @@ -126,6 +137,7 @@ def stop(self): self.shutdown_flag = True def run(self): + rpc_id = None while not self.shutdown_flag: try: jsonrpc_message = self.json_rpc_endpoint.recv_response() @@ -175,14 +187,14 @@ def send_message(self, method_name, params, id=None): message_dict["params"] = params self.json_rpc_endpoint.send_request(message_dict) - def call_method(self, method_name, **kwargs): + def call_method(self, method_name, args): current_id = self.next_id self.next_id += 1 cond = threading.Condition() self.event_dict[current_id] = cond cond.acquire() - self.send_message(method_name, kwargs, current_id) + self.send_message(method_name, args, current_id) if self.shutdown_flag: return None @@ -196,5 +208,17 @@ def call_method(self, method_name, **kwargs): raise ResponseError(error.get("code"), error.get("message"), error.get("data")) return result - def send_notification(self, method_name, **kwargs): + def send_notification(self, method_name, kwargs): self.send_message(method_name, kwargs) + + +class ServerBase: + def __init__(self, endpoint: LspEndpoint): + self.endpoint = endpoint + + def _call_sync(self, method_name: str, param: typing.List[object]) -> object: + resp = self.endpoint.call_method(method_name, param) + return resp + + def _call_async(self, method_name: str, param: typing.List[object]): + self.endpoint.send_notification(method_name, param) diff --git a/keyext.client.python/keyapi/server.py b/keyext.client.python/keyapi/server.py new file mode 100644 index 00000000000..2940363e1c2 --- /dev/null +++ b/keyext.client.python/keyapi/server.py @@ -0,0 +1,161 @@ +from __future__ import annotations + +import abc +from abc import abstractmethod + +from .keydata import * +from .rpc import ServerBase, LspEndpoint + + +# noinspection PyTypeChecker +class KeyServer(ServerBase): + + def __init__(self, endpoint: LspEndpoint): + super().__init__(endpoint) + + def env_contracts(self, env: EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self._call_sync("env/contracts", [env]) + + def env_functions(self, env: EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self._call_sync("env/functions", [env]) + + def env_openContract(self, contractId: ContractId) -> ProofId: + """""" + + return self._call_sync("env/openContract", [contractId]) + + def env_sorts(self, env: EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self._call_sync("env/sorts", [env]) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self._call_sync("examples/list", []) + + def goal_actions(self, id: NodeTextId, pos: int) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/actions", [id, pos]) + + def goal_apply_action(self, id: TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/apply_action", [id]) + + def goal_free(self, id: NodeTextId): + """""" + + return self._call_async("goal/free", [id]) + + def goal_print(self, id: NodeId, options: PrintOptions) -> NodeTextDesc: + """""" + + return self._call_sync("goal/print", [id, options]) + + def loading_load(self, params: LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self._call_sync("loading/load", [params]) + + def loading_loadExample(self, id: str) -> ProofId: + """""" + + return self._call_sync("loading/loadExample", [id]) + + def loading_loadKey(self, content: str) -> ProofId: + """""" + + return self._call_sync("loading/loadKey", [content]) + + def loading_loadProblem(self, problem: ProblemDefinition) -> ProofId: + """""" + + return self._call_sync("loading/loadProblem", [problem]) + + def loading_loadTerm(self, term: str) -> ProofId: + """""" + + return self._call_sync("loading/loadTerm", [term]) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self._call_sync("meta/available_macros", []) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self._call_sync("meta/available_script_commands", []) + + def meta_version(self, ) -> str: + """""" + + return self._call_sync("meta/version", []) + + def proofTree_children(self, proof: ProofId, nodeId: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/children", [proof, nodeId]) + + def proofTree_root(self, id: ProofId) -> TreeNodeDesc: + """""" + + return self._call_sync("proofTree/root", [id]) + + def proofTree_subtree(self, proof: ProofId, nodeId: TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/subtree", [proof, nodeId]) + + def server_exit(self, ): + """""" + + return self._call_async("server/exit", []) + + def server_setTrace(self, params: SetTraceParams): + """""" + + return self._call_async("server/setTrace", [params]) + + def server_shutdown(self, ) -> bool: + """""" + + return self._call_sync("server/shutdown", []) + + +class Client(abc.ABCMeta): + @abstractmethod + def client_logTrace(self, params: LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, e: str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, params: ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, params: ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, params: ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass diff --git a/keyext.client.python/main.py b/keyext.client.python/main.py index a5cb45321d8..d12fadea42a 100644 --- a/keyext.client.python/main.py +++ b/keyext.client.python/main.py @@ -1,5 +1,7 @@ import socket -from keyapi import KeyStub, KeyClient +from keyapi import LspEndpoint, LoadParams +from keyapi.server import KeyServer +from keyapi.rpc import JsonRpcEndpoint if __name__ == "__main__": target = ("localhost", 5151) @@ -8,6 +10,18 @@ s.connect(target) input = s.makefile("r", newline="\r\n") output = s.makefile("w", newline="\r\n") - stub = KeyStub(input, output) - stub.client = KeyClient() - print(stub.list_examples()) + + rpc_endpoint = JsonRpcEndpoint(input, output) + endpoint = LspEndpoint(rpc_endpoint) + endpoint.start() + + key = KeyServer(endpoint) + print(key.meta_version()) + ex = key.examples_list() + print(ex) + + proofHandle = key.loading_load( + LoadParams("/home/weigl/work/key/key.ui/examples/standard_key/prop_log/contraposition.key", + None, None, None, None)) + + print(proofHandle) diff --git a/keyext.client.python/rwtest.py b/keyext.client.python/rwtest.py deleted file mode 100644 index 312532192dc..00000000000 --- a/keyext.client.python/rwtest.py +++ /dev/null @@ -1,402 +0,0 @@ -import enum -import abc -import typing -from abc import abstractmethod - - -class ExampleDesc: - """""" - - name: str - description: str - - -class ProofScriptCommandDesc: - """""" - - -class ProofMacroDesc: - """""" - - name: str - category: str - description: str - scriptCommandName: str - - -class TraceValue(enum.Enum): - """""" - - Off = None - Message = None - All = None - - -class SetTraceParams: - """""" - - value: TraceValue - - -class EnvironmentId: - """""" - - envId: str - - -class ProofId: - """""" - - env: EnvironmentId - proofId: str - - -class TreeNodeDesc: - """""" - - -class TreeNodeId: - """""" - - id: str - - -class NodeId: - """""" - - proofId: ProofId - nodeId: int - - -class PrintOptions: - """""" - - unicode: bool - width: int - indentation: int - pure: bool - termLabels: bool - - -class NodeTextId: - """""" - - nodeId: NodeId - nodeTextId: int - - -class NodeTextDesc: - """""" - - id: NodeTextId - result: str - - -class TermActionId: - """""" - - nodeId: NodeId - pio: str - id: str - - -class TermActionKind(enum.Enum): - """""" - - BuiltIn = None - Script = None - Macro = None - Taclet = None - - -class TermActionDesc: - """""" - - commandId: TermActionId - displayName: str - description: str - category: str - kind: TermActionKind - - -class List: - """""" - - -class SortDesc: - """""" - - string: str - documentation: str - extendsSorts: List - anAbstract: bool - s: str - - -class FunctionDesc: - """""" - - name: str - sort: str - retSort: SortDesc - argSorts: List - rigid: bool - unique: bool - skolemConstant: bool - - -class ContractId: - """""" - - envId: EnvironmentId - contractId: int - - -class ContractDesc: - """""" - - contractId: ContractId - name: str - displayName: str - typeName: str - htmlText: str - plainText: str - - -class LoadParams: - """""" - - keyFile: str - javaFile: str - classPath: List - bootClassPath: str - includes: List - - -class ProblemDefinition: - """""" - - sorts: List - functions: List - predicates: List - antecTerms: List - succTerms: List - - -class LogTraceParams: - """""" - - messag: str - verbose: str - - -class MessageType(enum.Enum): - """""" - - Unused = None - Error = None - Warning = None - Info = None - Log = None - Debug = None - - -class ShowMessageParams: - """""" - - type: MessageType - message: str - - - -class ShowMessageRequestParams: - """""" - - type: MessageType - message: str - actions: typing.List[MessageActionItem] - - -class MessageActionItem: - """""" - - title: str - - -class Range: - """""" - - start: int - end: int - - -class ShowDocumentParams: - """""" - - uri: str - external: bool - takeFocus: bool - selection: Range - - -class ShowDocumentResult: - """""" - - success: bool - - -class TaskFinishedInfo: - """""" - - -class TaskStartedInfo: - """""" - - -class KeyServer(): - def env_contracts(self, arg0: EnvironmentId) -> typing.List[ContractDesc]: - """""" - - return self.rpc.call_sync("env/contracts", ) - - def env_functions(self, arg0: EnvironmentId) -> typing.List[FunctionDesc]: - """""" - - return self.rpc.call_sync("env/functions", ) - - def env_openContract(self, arg0: ContractId) -> ProofId: - """""" - - return self.rpc.call_sync("env/openContract", ) - - def env_sorts(self, arg0: EnvironmentId) -> typing.List[SortDesc]: - """""" - - return self.rpc.call_sync("env/sorts", ) - - def examples_list(self, ) -> typing.List[ExampleDesc]: - """""" - - return self.rpc.call_sync("examples/list", ) - - def goal_actions(self, arg0: NodeTextId, arg1: int) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/actions", ) - - def goal_apply_action(self, arg0: TermActionId) -> typing.List[TermActionDesc]: - """""" - - return self.rpc.call_sync("goal/apply_action", ) - - def goal_free(self, arg0: NodeTextId): - """""" - - return self.rpc.call_async("goal/free", ) - - def goal_print(self, arg0: NodeId, arg1: PrintOptions) -> NodeTextDesc: - """""" - - return self.rpc.call_sync("goal/print", ) - - def loading_load(self, arg0: LoadParams) -> typing.Union[EnvironmentId, ProofId]: - """""" - - return self.rpc.call_sync("loading/load", ) - - def loading_loadExample(self, arg0: str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadExample", ) - - def loading_loadKey(self, arg0: str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadKey", ) - - def loading_loadProblem(self, arg0: ProblemDefinition) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadProblem", ) - - def loading_loadTerm(self, arg0: str) -> ProofId: - """""" - - return self.rpc.call_sync("loading/loadTerm", ) - - def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: - """""" - - return self.rpc.call_sync("meta/available_macros", ) - - def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: - """""" - - return self.rpc.call_sync("meta/available_script_commands", ) - - def meta_version(self, ) -> str: - """""" - - return self.rpc.call_sync("meta/version", ) - - def proofTree_children(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/children", ) - - def proofTree_root(self, arg0: ProofId) -> TreeNodeDesc: - """""" - - return self.rpc.call_sync("proofTree/root", ) - - def proofTree_subtree(self, arg0: ProofId, arg1: TreeNodeId) -> typing.List[TreeNodeDesc]: - """""" - - return self.rpc.call_sync("proofTree/subtree", ) - - def server_exit(self, ): - """""" - - return self.rpc.call_async("server/exit", ) - - def server_setTrace(self, arg0: SetTraceParams): - """""" - - return self.rpc.call_async("server/setTrace", ) - - def server_shutdown(self, ) -> bool: - """""" - - return self.rpc.call_sync("server/shutdown", ) - - -class Client(abc.ABCMeta): - @abstractmethod - def client_logTrace(self, arg0: LogTraceParams): - """""" - - pass - - @abstractmethod - def client_sayHello(self, arg0: str): - """""" - - pass - - @abstractmethod - def client_showDocument(self, arg0: ShowDocumentParams) -> ShowDocumentResult: - """""" - - pass - - @abstractmethod - def client_sm(self, arg0: ShowMessageParams): - """""" - - pass - - @abstractmethod - def client_userResponse(self, arg0: ShowMessageRequestParams) -> MessageActionItem: - """""" - - pass diff --git a/server.py b/server.py new file mode 100644 index 00000000000..7ad103297fe --- /dev/null +++ b/server.py @@ -0,0 +1,159 @@ +from __future__ import annotations +from .keydata import * +from .rpc import ServerBase + +import enum +import abc +import typing +from abc import abstractmethod +class KeyServer(ServerBase): + + def __init__(self, endpoint : LspEndpoint): + super().__init__(endpoint) + + def env_contracts(self, env : EnvironmentId) -> typing.List[ContractDesc]: + """""" + + return self._call_sync("env/contracts", [env]) + + def env_functions(self, env : EnvironmentId) -> typing.List[FunctionDesc]: + """""" + + return self._call_sync("env/functions", [env]) + + def env_openContract(self, contractId : ContractId) -> ProofId: + """""" + + return self._call_sync("env/openContract", [contractId]) + + def env_sorts(self, env : EnvironmentId) -> typing.List[SortDesc]: + """""" + + return self._call_sync("env/sorts", [env]) + + def examples_list(self, ) -> typing.List[ExampleDesc]: + """""" + + return self._call_sync("examples/list", []) + + def goal_actions(self, id : NodeTextId, pos : int) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/actions", [id , pos]) + + def goal_apply_action(self, id : TermActionId) -> typing.List[TermActionDesc]: + """""" + + return self._call_sync("goal/apply_action", [id]) + + def goal_free(self, id : NodeTextId): + """""" + + return self._call_async("goal/free", [id]) + + def goal_print(self, id : NodeId, options : PrintOptions) -> NodeTextDesc: + """""" + + return self._call_sync("goal/print", [id , options]) + + def loading_load(self, params : LoadParams) -> typing.Union[EnvironmentId, ProofId]: + """""" + + return self._call_sync("loading/load", [params]) + + def loading_loadExample(self, id : str) -> ProofId: + """""" + + return self._call_sync("loading/loadExample", [id]) + + def loading_loadKey(self, content : str) -> ProofId: + """""" + + return self._call_sync("loading/loadKey", [content]) + + def loading_loadProblem(self, problem : ProblemDefinition) -> ProofId: + """""" + + return self._call_sync("loading/loadProblem", [problem]) + + def loading_loadTerm(self, term : str) -> ProofId: + """""" + + return self._call_sync("loading/loadTerm", [term]) + + def meta_available_macros(self, ) -> typing.List[ProofMacroDesc]: + """""" + + return self._call_sync("meta/available_macros", []) + + def meta_available_script_commands(self, ) -> typing.List[ProofScriptCommandDesc]: + """""" + + return self._call_sync("meta/available_script_commands", []) + + def meta_version(self, ) -> str: + """""" + + return self._call_sync("meta/version", []) + + def proofTree_children(self, proof : ProofId, nodeId : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/children", [proof , nodeId]) + + def proofTree_root(self, id : ProofId) -> TreeNodeDesc: + """""" + + return self._call_sync("proofTree/root", [id]) + + def proofTree_subtree(self, proof : ProofId, nodeId : TreeNodeId) -> typing.List[TreeNodeDesc]: + """""" + + return self._call_sync("proofTree/subtree", [proof , nodeId]) + + def server_exit(self, ): + """""" + + return self._call_async("server/exit", []) + + def server_setTrace(self, params : SetTraceParams): + """""" + + return self._call_async("server/setTrace", [params]) + + def server_shutdown(self, ) -> bool: + """""" + + return self._call_sync("server/shutdown", []) + +class Client(abc.ABCMeta): + @abstractmethod + def client_logTrace(self, params : LogTraceParams): + """""" + + pass + + @abstractmethod + def client_sayHello(self, e : str): + """""" + + pass + + @abstractmethod + def client_showDocument(self, params : ShowDocumentParams) -> ShowDocumentResult: + """""" + + pass + + @abstractmethod + def client_sm(self, params : ShowMessageParams): + """""" + + pass + + @abstractmethod + def client_userResponse(self, params : ShowMessageRequestParams) -> MessageActionItem: + """""" + + pass + From 993f90840fab82d74601337f6b1fa9ea463ce3dc Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Fri, 3 Nov 2023 17:58:48 +0100 Subject: [PATCH 17/50] add throwable adapter --- .../main/java/org/keyproject/key/api/StartServer.java | 2 +- .../org/keyproject/key/api/adapters/KeyAdapter.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index 26981875aef..b0491145cda 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -146,7 +146,7 @@ public void run() { public static void configureJson(GsonBuilder gsonBuilder) { gsonBuilder.registerTypeHierarchyAdapter(Object.class, new GenericSerializer()); gsonBuilder.registerTypeAdapter(File.class, new KeyAdapter.FileTypeAdapter()); - + gsonBuilder.registerTypeAdapter(Throwable.class, new KeyAdapter.ThrowableAdapter()); } public static Launcher launch(OutputStream out, InputStream in, KeyApiImpl keyApi) { diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index c17647c9e4f..67871cec674 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -74,6 +74,17 @@ public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationCont } } + public static class ThrowableAdapter implements JsonSerializer { + @Override + public JsonElement serialize(Throwable src, Type typeOfSrc, JsonSerializationContext context) { + var obj = new JsonObject(); + obj.add("$class", context.serialize(src.getClass().getSimpleName())); + obj.add("message", context.serialize(src.getMessage())); + obj.add("cause", context.serialize(src.getCause())); + return obj; + } + } + /*class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { @Override public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { From ae5f2157c79edb37e261d6d23776ffa65c6874e1 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sat, 18 Nov 2023 19:43:59 +0100 Subject: [PATCH 18/50] spotless and merge errors --- .../src/main/java/org/key_project/Main.java | 3 +- .../AbstractSymbolicExecutionTestCase.java | 1546 +++++++++-------- .../key/control/AbstractProofControl.java | 3 +- .../ilkd/key/control/DefaultProofControl.java | 27 +- .../uka/ilkd/key/control/KeYEnvironment.java | 125 +- .../de/uka/ilkd/key/control/ProofControl.java | 5 +- .../uka/ilkd/key/macros/ProofMacroFacade.java | 3 +- .../key/macros/ProofMacroFinishedInfo.java | 1 - .../scripts/ProofScriptCommandFacade.java | 4 +- .../main/java/de/uka/ilkd/key/proof/Goal.java | 2 +- .../main/java/de/uka/ilkd/key/proof/Node.java | 33 +- .../speclang/njml/ContractLoadingTests.java | 27 +- .../java/de/uka/ilkd/key/gui/Example.java | 24 +- .../de/uka/ilkd/key/gui/ProofMacroWorker.java | 25 +- .../key/gui/actions/RunAllProofsAction.java | 18 +- keyext.api.doc/src/main/java/DocGen.java | 165 +- .../src/main/java/ExtractMetaData.java | 99 +- keyext.api.doc/src/main/java/Metamodel.java | 86 +- .../src/main/java/PythionGenerator.java | 61 +- .../keyproject/key/api/GenericSerializer.java | 55 +- .../org/keyproject/key/api/KeyApiImpl.java | 153 +- .../org/keyproject/key/api/NodeTextId.java | 6 +- .../org/keyproject/key/api/StartServer.java | 34 +- .../keyproject/key/api/TermActionUtil.java | 91 +- .../key/api/adapters/KeyAdapter.java | 89 +- .../key/api/adapters/package-info.java | 2 +- .../keyproject/key/api/data/ContractDesc.java | 3 + .../keyproject/key/api/data/FunctionDesc.java | 7 +- .../key/api/data/KeyIdentifications.java | 33 +- .../keyproject/key/api/data/LoadParams.java | 3 + .../key/api/data/MacroDescription.java | 3 + .../key/api/data/MacroStatistic.java | 8 +- .../org/keyproject/key/api/data/NodeDesc.java | 7 +- .../keyproject/key/api/data/NodeTextDesc.java | 3 + .../key/api/data/PredicateDesc.java | 3 + .../key/api/data/ProblemDefinition.java | 7 +- .../key/api/data/ProofMacroDesc.java | 3 + .../key/api/data/ProofScriptCommandDesc.java | 3 + .../org/keyproject/key/api/data/SortDesc.java | 7 +- .../key/api/data/StreategyOptions.java | 3 + .../key/api/data/TermActionDesc.java | 3 + .../key/api/data/TermActionKind.java | 3 + .../keyproject/key/api/data/TraceValue.java | 3 + .../keyproject/key/api/data/TreeNodeDesc.java | 3 + .../keyproject/key/api/internal/NodeText.java | 5 +- .../keyproject/key/api/remoteapi/EnvApi.java | 9 +- .../key/api/remoteapi/ExampleApi.java | 10 +- .../key/api/remoteapi/ExampleDesc.java | 3 + .../keyproject/key/api/remoteapi/GoalApi.java | 11 +- .../keyproject/key/api/remoteapi/KeyApi.java | 6 +- .../keyproject/key/api/remoteapi/MetaApi.java | 11 +- .../key/api/remoteapi/PrintOptions.java | 3 + .../key/api/remoteapi/ProofApi.java | 16 +- .../key/api/remoteapi/ProofLoadApi.java | 17 +- .../key/api/remoteapi/ProofTreeApi.java | 9 +- .../key/api/remoteapi/ServerManagement.java | 20 +- .../key/api/remoteclient/ClientApi.java | 34 +- .../api/remoteclient/LogMessageParams.java | 3 + .../key/api/remoteclient/LogTraceParams.java | 3 + .../api/remoteclient/MessageActionItem.java | 3 + .../key/api/remoteclient/MessageType.java | 53 +- .../api/remoteclient/ShowDocumentParams.java | 3 + .../api/remoteclient/ShowDocumentResult.java | 3 + .../api/remoteclient/ShowMessageParams.java | 5 +- .../ShowMessageRequestParams.java | 3 + .../org/keyproject/key/api/SimpleClient.java | 10 +- .../java/org/keyproject/key/api/TestRpc.java | 19 +- .../ProofExplorationServiceTest.java | 38 +- .../ilkd/key/gui/testgen/TGInfoDialog.java | 9 +- 69 files changed, 1681 insertions(+), 1417 deletions(-) diff --git a/key.core.example/src/main/java/org/key_project/Main.java b/key.core.example/src/main/java/org/key_project/Main.java index 4da18d230e9..37530b71aa4 100644 --- a/key.core.example/src/main/java/org/key_project/Main.java +++ b/key.core.example/src/main/java/org/key_project/Main.java @@ -131,7 +131,8 @@ private static List getContracts(KeYEnvironment env) { * @param env the {@link KeYEnvironment} in which to prove the contract * @param contract the {@link Contract} to be proven */ - private static void proveContract(KeYEnvironment env, Contract contract) throws InterruptedException { + private static void proveContract(KeYEnvironment env, Contract contract) + throws InterruptedException { Proof proof = null; try { // Create proof diff --git a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java index 907a15d5c9d..ba7074ce7f7 100644 --- a/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java +++ b/key.core.symbolic_execution/src/test/java/de/uka/ilkd/key/symbolic_execution/testcase/AbstractSymbolicExecutionTestCase.java @@ -44,6 +44,7 @@ import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionUtil; import de.uka.ilkd.key.util.HelperClassForTests; import de.uka.ilkd.key.util.KeYConstants; + import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableList; @@ -51,15 +52,11 @@ import org.key_project.util.helper.FindResources; import org.key_project.util.java.CollectionUtil; import org.key_project.util.java.StringUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.util.*; - import static org.junit.jupiter.api.Assertions.*; /** @@ -69,7 +66,7 @@ */ public abstract class AbstractSymbolicExecutionTestCase { private static final Logger LOGGER = - LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); + LoggerFactory.getLogger(AbstractSymbolicExecutionTestCase.class); /** *

    @@ -86,7 +83,7 @@ public abstract class AbstractSymbolicExecutionTestCase { *

    */ public static final boolean CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY = - Boolean.getBoolean("UPDATE_TEST_ORACLE"); + Boolean.getBoolean("UPDATE_TEST_ORACLE"); static { @@ -102,13 +99,13 @@ public abstract class AbstractSymbolicExecutionTestCase { * Number of executed SET nodes to execute all in one. */ public static final int ALL_IN_ONE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN; /** * Number of executed SET nodes for only one SET node per auto mode run. */ public static final int SINGLE_SET_NODE_RUN = - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP; /** * Default stop conditions of executed SET nodes. @@ -135,9 +132,9 @@ public abstract class AbstractSymbolicExecutionTestCase { static { // Define fast mode if (FAST_MODE) { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN}; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN }; } else { - DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[]{ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN}; + DEFAULT_MAXIMAL_SET_NODES_PER_RUN = new int[] { ALL_IN_ONE_RUN, SINGLE_SET_NODE_RUN }; } // Create temporary director for oracle files if required. File directory = null; @@ -160,18 +157,18 @@ public abstract class AbstractSymbolicExecutionTestCase { /** * Creates a new oracle file. * - * @param node The node to save as oracle file. + * @param node The node to save as oracle file. * @param oraclePathInBaseDirFile The path in example directory. - * @param saveConstraints Save constraints? - * @param saveVariables Save variables? - * @param saveCallStack Save call stack? - * @param saveReturnValues Save method return values? - * @throws IOException Occurred Exception + * @param saveConstraints Save constraints? + * @param saveVariables Save variables? + * @param saveCallStack Save call stack? + * @param saveReturnValues Save method return values? + * @throws IOException Occurred Exception * @throws ProofInputException Occurred Exception */ protected static void createOracleFile(IExecutionNode node, String oraclePathInBaseDirFile, - boolean saveConstraints, boolean saveVariables, boolean saveCallStack, - boolean saveReturnValues) throws IOException, ProofInputException { + boolean saveConstraints, boolean saveVariables, boolean saveCallStack, + boolean saveReturnValues) throws IOException, ProofInputException { if (tempNewOracleDirectory != null && tempNewOracleDirectory.isDirectory()) { // Create sub folder structure File oracleFile = new File(tempNewOracleDirectory, oraclePathInBaseDirFile); @@ -179,7 +176,7 @@ protected static void createOracleFile(IExecutionNode node, String oraclePath // Create oracle file ExecutionNodeWriter writer = new ExecutionNodeWriter(); writer.write(node, ExecutionNodeWriter.DEFAULT_ENCODING, oracleFile, saveVariables, - saveCallStack, saveReturnValues, saveConstraints); + saveCallStack, saveReturnValues, saveConstraints); // Print message to the user. printOracleDirectory(); } @@ -207,37 +204,37 @@ protected static void printOracleDirectory() { /** * Makes sure that the given nodes and their subtrees contains the same content. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? - * @param compareChildOrder Is the order of children relevant? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? + * @param compareChildOrder Is the order of children relevant? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareCallStack, boolean compareChildOrder, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { if (compareChildOrder) { // Order of children must be the same. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { // Order of children is not relevant. ExecutionNodePreorderIterator expectedExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(expected); + new ExecutionNodePreorderIterator(expected); Set> currentVisitedNodes = new LinkedHashSet<>(); while (expectedExecutionTreeNodeIterator.hasNext()) { IExecutionNode expectedNext = expectedExecutionTreeNodeIterator.next(); @@ -246,11 +243,11 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo fail("Node " + currentNext + " visited twice."); } assertExecutionNode(expectedNext, currentNext, true, compareVariables, - compareCallStack, compareReturnValues, compareConstraints); + compareCallStack, compareReturnValues, compareConstraints); } // Make sure that each current node was visited ExecutionNodePreorderIterator actualExecutionTreeNodeIterator = - new ExecutionNodePreorderIterator(current); + new ExecutionNodePreorderIterator(current); while (actualExecutionTreeNodeIterator.hasNext()) { IExecutionNode currentNext = actualExecutionTreeNodeIterator.next(); if (!currentVisitedNodes.remove(currentNext)) { @@ -264,13 +261,13 @@ public static void assertExecutionNodes(IExecutionNode expected, IExecutionNo /** * Searches the direct or indirect child in subtree of the node to search in. * - * @param toSearchIn The node to search in. + * @param toSearchIn The node to search in. * @param childToSearch The node to search. * @return The found node. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearchIn, - IExecutionNode childToSearch) throws ProofInputException { + IExecutionNode childToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(toSearchIn); assertNotNull(childToSearch); @@ -291,20 +288,20 @@ protected static IExecutionNode searchExecutionNode(IExecutionNode toSearc } } assertNotNull(toSearchIn, "Direct or indirect Child " + childToSearch - + " is not contained in " + toSearchIn + "."); + + " is not contained in " + toSearchIn + "."); return toSearchIn; } /** * Searches the direct child. Nodes are equal if the name and the element type is equal. * - * @param parentToSearchIn The parent to search in its children. + * @param parentToSearchIn The parent to search in its children. * @param directChildToSearch The child to search. * @return The found child. * @throws ProofInputException Occurred Exception. */ protected static IExecutionNode searchDirectChildNode(IExecutionNode parentToSearchIn, - IExecutionNode directChildToSearch) throws ProofInputException { + IExecutionNode directChildToSearch) throws ProofInputException { // Make sure that parameters are valid assertNotNull(parentToSearchIn); assertNotNull(directChildToSearch); @@ -318,60 +315,60 @@ protected static IExecutionNode searchDirectChildNode(IExecutionNode paren if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) directChildToSearch) - .getAdditionalBranchLabel()) + ((IExecutionBranchCondition) children[i]).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) directChildToSearch) + .getAdditionalBranchLabel()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } else { if (StringUtil .equalIgnoreWhiteSpace(children[i].getName(), directChildToSearch.getName()) && children[i].getElementType() - .equals(directChildToSearch.getElementType())) { + .equals(directChildToSearch.getElementType())) { result = children[i]; } } i++; } assertNotNull(result, - "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); + "Child " + directChildToSearch + " is not contained in " + parentToSearchIn + "."); return result; } /** * Makes sure that the given nodes contains the same content. Children are not compared. * - * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. - * @param compareParent Compare also the parent node? - * @param compareVariables Compare variables? - * @param compareCallStack Compare call stack? + * @param expected The expected {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. + * @param compareParent Compare also the parent node? + * @param compareVariables Compare variables? + * @param compareCallStack Compare call stack? * @param compareReturnValues Compare return values? - * @param compareConstraints Compare constraints? + * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertExecutionNode(IExecutionNode expected, IExecutionNode current, - boolean compareParent, boolean compareVariables, boolean compareCallStack, - boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { + boolean compareParent, boolean compareVariables, boolean compareCallStack, + boolean compareReturnValues, boolean compareConstraints) throws ProofInputException { // Compare nodes assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); + "Expected \"" + expected.getName() + "\" but is \"" + current.getName() + "\"."); assertEquals(expected.isPathConditionChanged(), current.isPathConditionChanged()); if (!StringUtil.equalIgnoreWhiteSpace(expected.getFormatedPathCondition(), - current.getFormatedPathCondition())) { + current.getFormatedPathCondition())) { assertEquals(expected.getFormatedPathCondition(), current.getFormatedPathCondition()); } if (compareParent) { if (expected instanceof IExecutionBlockStartNode) { assertTrue(current instanceof IExecutionBlockStartNode); assertEquals(((IExecutionBlockStartNode) expected).isBlockOpened(), - ((IExecutionBlockStartNode) current).isBlockOpened()); + ((IExecutionBlockStartNode) current).isBlockOpened()); assertBlockCompletions((IExecutionBlockStartNode) expected, - (IExecutionBlockStartNode) current); + (IExecutionBlockStartNode) current); } assertCompletedBlocks(expected, current); assertOutgoingLinks(expected, current); @@ -380,177 +377,177 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution if (expected instanceof IExecutionBaseMethodReturn) { assertTrue(current instanceof IExecutionBaseMethodReturn); assertCallStateVariables((IExecutionBaseMethodReturn) expected, - (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); + (IExecutionBaseMethodReturn) current, compareVariables, compareConstraints); } if (expected instanceof IExecutionBranchCondition) { assertTrue(current instanceof IExecutionBranchCondition, - "Expected IExecutionBranchCondition but is " + current.getClass() + "."); + "Expected IExecutionBranchCondition but is " + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), - ((IExecutionBranchCondition) current).getFormatedBranchCondition()), - "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getFormatedBranchCondition(), + ((IExecutionBranchCondition) current).getFormatedBranchCondition()), + "Expected \"" + ((IExecutionBranchCondition) expected).getFormatedBranchCondition() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getFormatedBranchCondition() + "\"."); assertEquals(((IExecutionBranchCondition) expected).isMergedBranchCondition(), - ((IExecutionBranchCondition) current).isMergedBranchCondition()); + ((IExecutionBranchCondition) current).isMergedBranchCondition()); assertEquals(((IExecutionBranchCondition) expected).isBranchConditionComputed(), - ((IExecutionBranchCondition) current).isBranchConditionComputed()); + ((IExecutionBranchCondition) current).isBranchConditionComputed()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), - ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), - "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() - + "\" but is \"" - + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel(), + ((IExecutionBranchCondition) current).getAdditionalBranchLabel()), + "Expected \"" + ((IExecutionBranchCondition) expected).getAdditionalBranchLabel() + + "\" but is \"" + + ((IExecutionBranchCondition) current).getAdditionalBranchLabel() + "\"."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStart) { assertTrue(current instanceof IExecutionStart, "Expected IExecutionStartNode but is " - + current.getClass() + "."); + + current.getClass() + "."); assertTerminations((IExecutionStart) expected, (IExecutionStart) current); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionTermination) { assertTrue(current instanceof IExecutionTermination, - "Expected IExecutionTermination but is " - + current.getClass() + "."); + "Expected IExecutionTermination but is " + + current.getClass() + "."); assertEquals(((IExecutionTermination) expected).getTerminationKind(), - ((IExecutionTermination) current).getTerminationKind()); + ((IExecutionTermination) current).getTerminationKind()); assertEquals(((IExecutionTermination) expected).isBranchVerified(), - ((IExecutionTermination) current).isBranchVerified()); + ((IExecutionTermination) current).isBranchVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionBranchStatement) { assertTrue(current instanceof IExecutionBranchStatement, - "Expected IExecutionBranchStatement but is " - + current.getClass() + "."); + "Expected IExecutionBranchStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopCondition) { assertTrue(current instanceof IExecutionLoopCondition, - "Expected IExecutionLoopCondition but is " - + current.getClass() + "."); + "Expected IExecutionLoopCondition but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopStatement) { assertTrue(current instanceof IExecutionLoopStatement, - "Expected IExecutionLoopStatement but is " - + current.getClass() + "."); + "Expected IExecutionLoopStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionMethodCall) { assertTrue(current instanceof IExecutionMethodCall, - "Expected IExecutionMethodCall but is " - + current.getClass() + "."); + "Expected IExecutionMethodCall but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); assertMethodReturns((IExecutionMethodCall) expected, (IExecutionMethodCall) current); } else if (expected instanceof IExecutionMethodReturn) { assertTrue(current instanceof IExecutionMethodReturn, - "Expected IExecutionMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), - ((IExecutionMethodReturn) current).getSignature()), - ((IExecutionMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace(((IExecutionMethodReturn) expected).getSignature(), + ((IExecutionMethodReturn) current).getSignature()), + ((IExecutionMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionMethodReturn) current).getSignature()); if (compareReturnValues) { assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), - ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue(), + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getNameIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getNameIncludingReturnValue()); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), - ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), - ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() - + " does not match " - + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue(), + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()), + ((IExecutionMethodReturn) expected).getSignatureIncludingReturnValue() + + " does not match " + + ((IExecutionMethodReturn) current).getSignatureIncludingReturnValue()); assertEquals(((IExecutionMethodReturn) expected).isReturnValuesComputed(), - ((IExecutionMethodReturn) current).isReturnValuesComputed()); + ((IExecutionMethodReturn) current).isReturnValuesComputed()); } assertTrue( - StringUtil.equalIgnoreWhiteSpace( + StringUtil.equalIgnoreWhiteSpace( ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + + " does not match " + ((IExecutionMethodReturn) current).getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); if (compareReturnValues) { assertReturnValues(((IExecutionMethodReturn) expected).getReturnValues(), - ((IExecutionMethodReturn) current).getReturnValues()); + ((IExecutionMethodReturn) current).getReturnValues()); } } else if (expected instanceof IExecutionExceptionalMethodReturn) { assertTrue(current instanceof IExecutionExceptionalMethodReturn, - "Expected IExecutionExceptionalMethodReturn but is " - + current.getClass() + "."); + "Expected IExecutionExceptionalMethodReturn but is " + + current.getClass() + "."); assertTrue( - StringUtil.equalIgnoreWhiteSpace( - ((IExecutionExceptionalMethodReturn) expected).getSignature(), - ((IExecutionExceptionalMethodReturn) current).getSignature()), - ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " - + ((IExecutionExceptionalMethodReturn) current).getSignature()); + StringUtil.equalIgnoreWhiteSpace( + ((IExecutionExceptionalMethodReturn) expected).getSignature(), + ((IExecutionExceptionalMethodReturn) current).getSignature()), + ((IExecutionExceptionalMethodReturn) expected).getSignature() + " does not match " + + ((IExecutionExceptionalMethodReturn) current).getSignature()); assertTrue(StringUtil.equalIgnoreWhiteSpace( ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition(), ((IExecutionExceptionalMethodReturn) current).getFormattedMethodReturnCondition()), ((IExecutionExceptionalMethodReturn) expected).getFormattedMethodReturnCondition() - + " does not match " + ((IExecutionExceptionalMethodReturn) current) + + " does not match " + ((IExecutionExceptionalMethodReturn) current) .getFormattedMethodReturnCondition()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionStatement) { assertTrue(current instanceof IExecutionStatement, - "Expected IExecutionStatement but is " - + current.getClass() + "."); + "Expected IExecutionStatement but is " + + current.getClass() + "."); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionOperationContract) { assertTrue(current instanceof IExecutionOperationContract, - "Expected IExecutionOperationContract but is " - + current.getClass() + "."); + "Expected IExecutionOperationContract but is " + + current.getClass() + "."); assertEquals(((IExecutionOperationContract) expected).isPreconditionComplied(), - ((IExecutionOperationContract) current).isPreconditionComplied()); + ((IExecutionOperationContract) current).isPreconditionComplied()); assertEquals(((IExecutionOperationContract) expected).hasNotNullCheck(), - ((IExecutionOperationContract) current).hasNotNullCheck()); + ((IExecutionOperationContract) current).hasNotNullCheck()); assertEquals(((IExecutionOperationContract) expected).isNotNullCheckComplied(), - ((IExecutionOperationContract) current).isNotNullCheckComplied()); + ((IExecutionOperationContract) current).isNotNullCheckComplied()); assertEquals(((IExecutionOperationContract) expected).getFormatedResultTerm(), - ((IExecutionOperationContract) current).getFormatedResultTerm()); + ((IExecutionOperationContract) current).getFormatedResultTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedExceptionTerm(), - ((IExecutionOperationContract) current).getFormatedExceptionTerm()); + ((IExecutionOperationContract) current).getFormatedExceptionTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedSelfTerm(), - ((IExecutionOperationContract) current).getFormatedSelfTerm()); + ((IExecutionOperationContract) current).getFormatedSelfTerm()); assertEquals(((IExecutionOperationContract) expected).getFormatedContractParams(), - ((IExecutionOperationContract) current).getFormatedContractParams()); + ((IExecutionOperationContract) current).getFormatedContractParams()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionLoopInvariant) { assertTrue(current instanceof IExecutionLoopInvariant, - "Expected IExecutionLoopInvariant but is " - + current.getClass() + "."); + "Expected IExecutionLoopInvariant but is " + + current.getClass() + "."); assertEquals(((IExecutionLoopInvariant) expected).isInitiallyValid(), - ((IExecutionLoopInvariant) current).isInitiallyValid()); + ((IExecutionLoopInvariant) current).isInitiallyValid()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionAuxiliaryContract) { assertTrue(current instanceof IExecutionAuxiliaryContract, - "Expected IExecutionBlockContract but is " - + current.getClass() + "."); + "Expected IExecutionBlockContract but is " + + current.getClass() + "."); assertEquals(((IExecutionAuxiliaryContract) expected).isPreconditionComplied(), - ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); + ((IExecutionAuxiliaryContract) current).isPreconditionComplied()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else if (expected instanceof IExecutionJoin) { assertTrue(current instanceof IExecutionJoin, "Expected IExecutionJoin but is " - + current.getClass() + "."); + + current.getClass() + "."); assertEquals(((IExecutionJoin) expected).isWeakeningVerified(), - ((IExecutionJoin) current).isWeakeningVerified()); + ((IExecutionJoin) current).isWeakeningVerified()); assertVariables(expected, current, compareVariables, compareConstraints); assertConstraints(expected, current, compareConstraints); } else { @@ -562,22 +559,22 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution IExecutionNode[] currentStack = current.getCallStack(); if (expectedStack != null) { assertNotNull(currentStack, - "Call stack of \"" + current + "\" should not be null."); + "Call stack of \"" + current + "\" should not be null."); assertEquals(expectedStack.length, currentStack.length, "Node: " + expected); for (int i = 0; i < expectedStack.length; i++) { assertExecutionNode(expectedStack[i], currentStack[i], false, false, false, - false, false); + false, false); } } else { assertTrue(currentStack == null || currentStack.length == 0, - "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) - + "\" but should be null or empty."); + "Call stack of \"" + current + "\" is \"" + Arrays.toString(currentStack) + + "\" but should be null or empty."); } } // Optionally compare parent if (compareParent) { assertExecutionNode(expected, current, false, compareVariables, compareCallStack, - compareReturnValues, compareConstraints); + compareReturnValues, compareConstraints); } } @@ -585,7 +582,7 @@ protected static void assertExecutionNode(IExecutionNode expected, IExecution * Compares the outgoing links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertOutgoingLinks(IExecutionNode expected, IExecutionNode current) @@ -594,9 +591,9 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getOutgoingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Outgoing links of \"" + current + "\" should not be null."); + "Outgoing links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Outgoing links: " + expected); + "Outgoing links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -604,15 +601,15 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Outgoing links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -620,7 +617,7 @@ protected static void assertOutgoingLinks(IExecutionNode expected, IExecution * Compares the incoming links. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertIncomingLinks(IExecutionNode expected, IExecutionNode current) @@ -629,9 +626,9 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution ImmutableList currentEntries = current.getIncomingLinks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Incoming links of \"" + current + "\" should not be null."); + "Incoming links of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), - "Incoming links: " + expected); + "Incoming links: " + expected); Iterator expectedExecutionTreeNodeIterator = expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() @@ -639,15 +636,15 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution IExecutionLink expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionLink currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext.getSource(), currentNext.getSource(), false, false, - false, false, false); + false, false, false); assertExecutionNode(expectedNext.getTarget(), currentNext.getTarget(), false, false, - false, false, false); + false, false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), "Incoming links of \"" - + current + "\" is \"" + currentEntries + "\" but should be null or empty."); + + current + "\" is \"" + currentEntries + "\" but should be null or empty."); } } @@ -655,29 +652,29 @@ protected static void assertIncomingLinks(IExecutionNode expected, IExecution * Compares the completed blocks. * * @param expected The expected {@link IExecutionNode}. - * @param current The current {@link IExecutionNode}. + * @param current The current {@link IExecutionNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertCompletedBlocks(IExecutionNode expected, - IExecutionNode current) throws ProofInputException { + IExecutionNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getCompletedBlocks(); ImmutableList> currentEntries = current.getCompletedBlocks(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Completed blocks of \"" + current + "\" should not be null."); + "Completed blocks of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { IExecutionBlockStartNode expectedNext = expectedExecutionTreeNodeIterator.next(); IExecutionBlockStartNode currentNext = actualExecutionTreeNodeIterator.next(); assertExecutionNode(expectedNext, currentNext, false, false, - false, false, false); + false, false, false); String expectedCondition = - expected.getFormatedBlockCompletionCondition(expectedNext); + expected.getFormatedBlockCompletionCondition(expectedNext); String currentCondition = current.getFormatedBlockCompletionCondition(currentNext); if (!StringUtil.equalIgnoreWhiteSpace(expectedCondition, currentCondition)) { assertEquals(expectedCondition, currentCondition); @@ -687,8 +684,8 @@ protected static void assertCompletedBlocks(IExecutionNode expected, assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Completed block entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Completed block entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -696,33 +693,33 @@ protected static void assertCompletedBlocks(IExecutionNode expected, * Compares the block completions. * * @param expected The expected {@link IExecutionBlockStartNode}. - * @param current The current {@link IExecutionBlockStartNode}. + * @param current The current {@link IExecutionBlockStartNode}. * @throws ProofInputException Occurred Exception. */ protected static void assertBlockCompletions(IExecutionBlockStartNode expected, - IExecutionBlockStartNode current) throws ProofInputException { + IExecutionBlockStartNode current) throws ProofInputException { ImmutableList> expectedEntries = expected.getBlockCompletions(); ImmutableList> currentEntries = current.getBlockCompletions(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Block completions of \"" + current + "\" should not be null."); + "Block completions of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Block completion entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Block completion entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -730,34 +727,34 @@ protected static void assertBlockCompletions(IExecutionBlockStartNode expecte * Compares the method returns. * * @param expected The expected {@link IExecutionMethodCall}. - * @param current The current {@link IExecutionMethodCall}. + * @param current The current {@link IExecutionMethodCall}. * @throws ProofInputException Occurred Exception. */ protected static void assertMethodReturns(IExecutionMethodCall expected, - IExecutionMethodCall current) throws ProofInputException { + IExecutionMethodCall current) throws ProofInputException { ImmutableList> expectedEntries = expected.getMethodReturns(); ImmutableList> currentEntries = current.getMethodReturns(); if (expectedEntries != null) { assertNotNull(currentEntries, - "Method return of \"" + current + "\" should not be null."); + "Method return of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator> expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator> actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Method return entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Method return entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -765,7 +762,7 @@ protected static void assertMethodReturns(IExecutionMethodCall expected, * Compares the terminations. * * @param expected The expected {@link IExecutionStart}. - * @param current The current {@link IExecutionStart}. + * @param current The current {@link IExecutionStart}. * @throws ProofInputException Occurred Exception. */ protected static void assertTerminations(IExecutionStart expected, IExecutionStart current) @@ -776,22 +773,22 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta assertNotNull(currentEntries, "Termination of \"" + current + "\" should not be null."); assertEquals(expectedEntries.size(), currentEntries.size(), "Node: " + expected); Iterator expectedExecutionTreeNodeIterator = - expectedEntries.iterator(); + expectedEntries.iterator(); Iterator actualExecutionTreeNodeIterator = - currentEntries.iterator(); + currentEntries.iterator(); while (expectedExecutionTreeNodeIterator.hasNext() && actualExecutionTreeNodeIterator.hasNext()) { assertExecutionNode(expectedExecutionTreeNodeIterator.next(), - actualExecutionTreeNodeIterator.next(), - false, false, false, - false, false); + actualExecutionTreeNodeIterator.next(), + false, false, false, + false, false); } assertFalse(expectedExecutionTreeNodeIterator.hasNext()); assertFalse(actualExecutionTreeNodeIterator.hasNext()); } else { assertTrue(currentEntries == null || currentEntries.isEmpty(), - "Termination entries of \"" + current + "\" is \"" + currentEntries - + "\" but should be null or empty."); + "Termination entries of \"" + current + "\" is \"" + currentEntries + + "\" but should be null or empty."); } } @@ -799,11 +796,11 @@ protected static void assertTerminations(IExecutionStart expected, IExecutionSta * Makes sure that the given nodes contains the same {@link IExecutionMethodReturnValue}s. * * @param expected The expected {@link IExecutionMethodReturnValue}s. - * @param current The current {@link IExecutionMethodReturnValue}s. + * @param current The current {@link IExecutionMethodReturnValue}s. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, - IExecutionMethodReturnValue[] current) throws ProofInputException { + IExecutionMethodReturnValue[] current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertEquals(expected.length, current.length); @@ -816,36 +813,36 @@ protected static void assertReturnValues(IExecutionMethodReturnValue[] expected, * Makes sure that the given {@link IExecutionMethodReturnValue}s are the same. * * @param expected The expected {@link IExecutionMethodReturnValue}. - * @param current The current {@link IExecutionMethodReturnValue}. + * @param current The current {@link IExecutionMethodReturnValue}. * @throws ProofInputException Occurred Exception. */ protected static void assertReturnValue(IExecutionMethodReturnValue expected, - IExecutionMethodReturnValue current) throws ProofInputException { + IExecutionMethodReturnValue current) throws ProofInputException { assertNotNull(expected); assertNotNull(current); assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), - current.getReturnValueString()), - expected.getReturnValueString() + " does not match " + current.getReturnValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getReturnValueString(), + current.getReturnValueString()), + expected.getReturnValueString() + " does not match " + current.getReturnValueString()); assertEquals(expected.hasCondition(), current.hasCondition()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); } /** * Makes sure that the given nodes contains the same {@link IExecutionNode}s. * - * @param expected The expected node. - * @param current The current node. + * @param expected The expected node. + * @param current The current node. * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionNode expected, IExecutionNode current, - boolean compareConstraints) throws ProofInputException { + boolean compareConstraints) throws ProofInputException { if (compareConstraints) { assertNotNull(expected); assertNotNull(current); @@ -859,26 +856,26 @@ protected static void assertConstraints(IExecutionNode expected, IExecutionNo * Makes sure that the given constraints are the same. * * @param expected The expected constraints. - * @param current The current constraints. + * @param current The current constraints. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraints(IExecutionConstraint[] expected, - IExecutionConstraint[] current) throws ProofInputException { + IExecutionConstraint[] current) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionConstraint expectedVariable : expected) { // Find current variable with same name IExecutionConstraint currentVariable = CollectionUtil.searchAndRemove( - availableCurrentVariables, element -> { - try { - return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); - } catch (ProofInputException e) { - throw new RuntimeException(e); - } - }); + availableCurrentVariables, element -> { + try { + return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), + element.getName()); + } catch (ProofInputException e) { + throw new RuntimeException(e); + } + }); assertNotNull(currentVariable); // Compare variables assertConstraint(expectedVariable, currentVariable); @@ -890,11 +887,11 @@ protected static void assertConstraints(IExecutionConstraint[] expected, * Makes sure that the given constraints are the same. * * @param expected The expected constraint. - * @param current The current constraint. + * @param current The current constraint. * @throws ProofInputException Occurred Exception. */ protected static void assertConstraint(IExecutionConstraint expected, - IExecutionConstraint current) throws ProofInputException { + IExecutionConstraint current) throws ProofInputException { if (expected != null) { assertNotNull(current); if (!StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName())) { @@ -909,15 +906,15 @@ protected static void assertConstraint(IExecutionConstraint expected, * Makes sure that the given nodes contains the same {@link IExecutionVariable}s of the call * state. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertCallStateVariables(IExecutionBaseMethodReturn expected, - IExecutionBaseMethodReturn current, boolean compareVariables, - boolean compareConstraints) throws ProofInputException { + IExecutionBaseMethodReturn current, boolean compareVariables, + boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -930,14 +927,14 @@ protected static void assertCallStateVariables(IExecutionBaseMethodReturn exp /** * Makes sure that the given nodes contains the same {@link IExecutionVariable}s. * - * @param expected The expected node. - * @param current The current node. - * @param compareVariables Compare variables? + * @param expected The expected node. + * @param current The current node. + * @param compareVariables Compare variables? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionNode expected, IExecutionNode current, - boolean compareVariables, boolean compareConstraints) throws ProofInputException { + boolean compareVariables, boolean compareConstraints) throws ProofInputException { if (compareVariables) { assertNotNull(expected); assertNotNull(current); @@ -950,27 +947,27 @@ protected static void assertVariables(IExecutionNode expected, IExecutionNode /** * Makes sure that the given variables are the same. * - * @param expected The expected variables. - * @param current The current variables. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variables. + * @param current The current variables. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariables(IExecutionVariable[] expected, - IExecutionVariable[] current, boolean compareParent, boolean compareChildren, - boolean compareConstraints) throws ProofInputException { + IExecutionVariable[] current, boolean compareParent, boolean compareChildren, + boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order List availableCurrentVariables = - new ArrayList<>(Arrays.asList(current)); + new ArrayList<>(Arrays.asList(current)); for (final IExecutionVariable expectedVariable : expected) { // Find current variable with same name IExecutionVariable currentVariable = CollectionUtil .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()); + element.getName()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -978,7 +975,7 @@ protected static void assertVariables(IExecutionVariable[] expected, assertNotNull(currentVariable); // Compare variables assertVariable(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -986,15 +983,15 @@ protected static void assertVariables(IExecutionVariable[] expected, /** * Makes sure that the given variables are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertVariable(IExecutionVariable expected, IExecutionVariable current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); @@ -1005,7 +1002,7 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari // Compare parent if (compareParent) { assertValue(expected.getParentValue(), current.getParentValue(), false, false, - false); + false); } // Compare children if (compareChildren) { @@ -1021,15 +1018,15 @@ protected static void assertVariable(IExecutionVariable expected, IExecutionVari /** * Makes sure that the given values are the same. * - * @param expected The expected values. - * @param current The current values. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected values. + * @param current The current values. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { assertEquals(expected.length, current.length); // Compare ignore order @@ -1040,10 +1037,10 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] .searchAndRemove(availableCurrentVariables, element -> { try { return StringUtil.equalIgnoreWhiteSpace(expectedVariable.getName(), - element.getName()) + element.getName()) && StringUtil.equalIgnoreWhiteSpace( - expectedVariable.getConditionString(), - element.getConditionString()); + expectedVariable.getConditionString(), + element.getConditionString()); } catch (ProofInputException e) { throw new RuntimeException(e); } @@ -1051,7 +1048,7 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] assertNotNull(currentVariable); // Compare variables assertValue(expectedVariable, currentVariable, compareParent, compareChildren, - compareConstraints); + compareConstraints); } assertTrue(availableCurrentVariables.isEmpty()); } @@ -1059,43 +1056,43 @@ protected static void assertValues(IExecutionValue[] expected, IExecutionValue[] /** * Makes sure that the given values are the same. * - * @param expected The expected variable. - * @param current The current variable. - * @param compareParent Compare parent? - * @param compareChildren Compare children? + * @param expected The expected variable. + * @param current The current variable. + * @param compareParent Compare parent? + * @param compareChildren Compare children? * @param compareConstraints Compare constraints? * @throws ProofInputException Occurred Exception. */ protected static void assertValue(IExecutionValue expected, IExecutionValue current, - boolean compareParent, boolean compareChildren, boolean compareConstraints) + boolean compareParent, boolean compareChildren, boolean compareConstraints) throws ProofInputException { if (expected != null) { assertNotNull(current); // Compare variable assertTrue(StringUtil.equalIgnoreWhiteSpace(expected.getName(), current.getName()), - expected.getName() + " does not match " + current.getName()); + expected.getName() + " does not match " + current.getName()); assertEquals(expected.getTypeString(), current.getTypeString()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), - current.getValueString()), - expected.getValueString() + " does not match " + current.getValueString()); + StringUtil.equalIgnoreWhiteSpace(expected.getValueString(), + current.getValueString()), + expected.getValueString() + " does not match " + current.getValueString()); assertEquals(expected.isValueAnObject(), current.isValueAnObject()); assertEquals(expected.isValueUnknown(), current.isValueUnknown()); assertTrue( - StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), - current.getConditionString()), - expected.getConditionString() + " does not match " + current.getConditionString()); + StringUtil.equalIgnoreWhiteSpace(expected.getConditionString(), + current.getConditionString()), + expected.getConditionString() + " does not match " + current.getConditionString()); // Compare parent if (compareParent) { assertVariable(expected.getVariable(), current.getVariable(), false, false, - compareConstraints); + compareConstraints); } // Compare children if (compareChildren) { IExecutionVariable[] expectedChildVariables = expected.getChildVariables(); IExecutionVariable[] currentChildVariables = current.getChildVariables(); assertVariables(expectedChildVariables, currentChildVariables, compareParent, - compareChildren, compareConstraints); + compareChildren, compareConstraints); } // Compare constraints if (compareConstraints) { @@ -1112,27 +1109,27 @@ protected static void assertValue(IExecutionValue expected, IExecutionValue curr * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturn(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); @@ -1142,8 +1139,9 @@ protected static void stepReturn(DefaultUserInterfaceControl ui, // Update symbolic execution tree builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -1154,27 +1152,27 @@ protected static void stepReturn(DefaultUserInterfaceControl ui, * Executes a "step return" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir, CompoundStopCondition lineBreakpoints) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepReturnSymbolicExecutionTreeNodesStopCondition()); stopCondition.addChildren(lineBreakpoints); proof.getSettings().getStrategySettings() @@ -1185,8 +1183,9 @@ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, // Update symbolic execution tree builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -1196,27 +1195,27 @@ protected static void stepReturnWithBreakpoints(DefaultUserInterfaceControl ui, * Executes a "step over" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void stepOver(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); CompoundStopCondition stopCondition = new CompoundStopCondition(); stopCondition.addChildren(new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN)); stopCondition.addChildren(new StepOverSymbolicExecutionTreeNodesStopCondition()); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); @@ -1226,8 +1225,9 @@ protected static void stepOver(DefaultUserInterfaceControl ui, // Update symbolic execution tree builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -1237,28 +1237,28 @@ protected static void stepOver(DefaultUserInterfaceControl ui, * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. * @return The found {@link SymbolicExecutionCompletions}. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, - String oracleFileExtension, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, int oracleIndex, + String oracleFileExtension, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_FOR_ONE_STEP); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof @@ -1268,8 +1268,9 @@ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceContr // Update symbolic execution tree SymbolicExecutionCompletions completions = builder.analyse(); // Test result - assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, oracleFileExtension, - baseDir); + assertSetTreeAfterStep(builder, oraclePathInBaseDirFile, oracleIndex, + oracleFileExtension, + baseDir); return completions; } catch (InterruptedException e) { throw new RuntimeException(e); @@ -1280,24 +1281,24 @@ protected static SymbolicExecutionCompletions stepInto(DefaultUserInterfaceContr * Executes a "step into" global on all goals on the given * {@link SymbolicExecutionTreeBuilder}. * - * @param ui The {@link DefaultUserInterfaceControl} to use. - * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. + * @param ui The {@link DefaultUserInterfaceControl} to use. + * @param builder The {@link SymbolicExecutionGoalChooser} to do step on. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void resume(DefaultUserInterfaceControl ui, - SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) + SymbolicExecutionTreeBuilder builder, String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules Proof proof = builder.getProof(); ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition( - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); + new ExecutedSymbolicExecutionTreeNodesStopCondition( + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN); proof.getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); // Run proof @@ -1316,20 +1317,20 @@ protected static void resume(DefaultUserInterfaceControl ui, /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, File baseDir) + String oraclePathInBaseDirFile, File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { if (CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { createOracleFile(builder.getStartNode(), oraclePathInBaseDirFile, false, false, false, - false); + false); } else { // Read oracle file File oracleFile = new File(baseDir, oraclePathInBaseDirFile); @@ -1338,41 +1339,41 @@ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builde assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, builder.getStartNode(), false, false, false, false, - false); + false); } } /** * Makes sure that after a step the correct set tree is created. * - * @param builder The {@link SymbolicExecutionTreeBuilder} to test. + * @param builder The {@link SymbolicExecutionTreeBuilder} to test. * @param oraclePathInBaseDirFile The oracle path. - * @param oracleIndex The index of the current step. - * @param oracleFileExtension The oracle file extension - * @param baseDir The base directory for oracles. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param oracleIndex The index of the current step. + * @param oracleFileExtension The oracle file extension + * @param baseDir The base directory for oracles. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception + * @throws SAXException Occurred Exception */ protected static void assertSetTreeAfterStep(SymbolicExecutionTreeBuilder builder, - String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, - File baseDir) + String oraclePathInBaseDirFile, int oracleIndex, String oracleFileExtension, + File baseDir) throws IOException, ProofInputException, ParserConfigurationException, SAXException { assertSetTreeAfterStep(builder, - oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); + oraclePathInBaseDirFile + "_" + oracleIndex + oracleFileExtension, baseDir); } /** * Searches a {@link IProgramMethod} in the given {@link Services}. * - * @param services The {@link Services} to search in. + * @param services The {@link Services} to search in. * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. + * @param methodFullName The method name to search. * @return The first found {@link IProgramMethod} in the type. */ public static IProgramMethod searchProgramMethod(Services services, String containerTypeName, - final String methodFullName) { + final String methodFullName) { return HelperClassForTests.searchProgramMethod(services, containerTypeName, methodFullName); } @@ -1381,29 +1382,29 @@ public static IProgramMethod searchProgramMethod(Services services, String conta * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param baseContractName The name of the contract. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param baseContractName The name of the contract. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String baseContractName, @@ -1417,26 +1418,26 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, - null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), javaFile, + null, null, null, true); setupTacletOptions(environment); // Start proof final Contract contract = environment.getServices().getSpecificationRepository() .getContractByName(baseContractName); assertTrue(contract instanceof FunctionalOperationContract); ProofOblInput input = new FunctionalOperationContractPO(environment.getInitConfig(), - (FunctionalOperationContract) contract, true, true); + (FunctionalOperationContract) contract, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1448,30 +1449,30 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1485,25 +1486,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodPO(environment.getInitConfig(), pm.getFullName(), pm, - precondition, true, true); + precondition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1526,26 +1527,26 @@ private static void setupTacletOptions(KeYEnvironment env) { * Creates a {@link SymbolicExecutionEnvironment} which consists of loading a proof file to load * and creation with configuration of {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param proofPathInBaseDir The path to the proof file inside the base directory. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofPathInBaseDir The path to the proof file inside the base directory. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. */ @@ -1562,20 +1563,20 @@ protected static SymbolicExecutionEnvironment creat assertTrue(proofFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, - null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(truthValueEvaluationEnabled), proofFile, + null, null, null, SymbolicExecutionTreeBuilder.createPoPropertiesToForce(), null, true); setupTacletOptions(environment); Proof proof = environment.getLoadedProof(); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1587,32 +1588,32 @@ protected static SymbolicExecutionEnvironment creat * finding the method to proof, instantiation of proof and creation with configuration of * {@link SymbolicExecutionTreeBuilder}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The name of the type which contains the method. - * @param methodFullName The method name to search. - * @param precondition An optional precondition to use. - * @param startPosition The start position. - * @param endPosition The end position. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The name of the type which contains the method. + * @param methodFullName The method name to search. + * @param precondition An optional precondition to use. + * @param startPosition The start position. + * @param endPosition The end position. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The created {@link SymbolicExecutionEnvironment}. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ protected static SymbolicExecutionEnvironment createSymbolicExecutionEnvironment( File baseDir, String javaPathInBaseDir, String containerTypeName, String methodFullName, @@ -1627,25 +1628,25 @@ protected static SymbolicExecutionEnvironment creat assertTrue(javaFile.exists()); // Load java file KeYEnvironment environment = KeYEnvironment.load( - SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); + SymbolicExecutionJavaProfile.getDefaultInstance(), javaFile, null, null, null, true); setupTacletOptions(environment); // Search method to proof IProgramMethod pm = - searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); + searchProgramMethod(environment.getServices(), containerTypeName, methodFullName); // Start proof ProofOblInput input = new ProgramMethodSubsetPO(environment.getInitConfig(), methodFullName, - pm, precondition, startPosition, endPosition, true, true); + pm, precondition, startPosition, endPosition, true, true); Proof proof = environment.createProof(input); assertNotNull(proof); // Set strategy and goal chooser to use for auto mode SymbolicExecutionEnvironment.configureProofForSymbolicExecution(proof, - ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks); + ExecutedSymbolicExecutionTreeNodesStopCondition.MAXIMAL_NUMBER_OF_SET_NODES_TO_EXECUTE_PER_GOAL_IN_COMPLETE_RUN, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks); // Create symbolic execution tree which contains only the start node at beginning SymbolicExecutionTreeBuilder builder = - new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + new SymbolicExecutionTreeBuilder(proof, mergeBranchConditions, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); SymbolicExecutionUtil.initializeStrategy(builder); builder.analyse(); assertNotNull(builder.getStartNode()); @@ -1670,7 +1671,7 @@ protected String getTryContent(Proof proof) { JavaProgramElement updateContent = updateApplication.subs().get(1).javaBlock().program(); assertTrue(updateContent instanceof StatementBlock); ImmutableArray updateContentBody = - ((StatementBlock) updateContent).getBody(); + ((StatementBlock) updateContent).getBody(); assertEquals(2, updateContentBody.size()); assertTrue(updateContentBody.get(1) instanceof Try); Try tryStatement = (Try) updateContentBody.get(1); @@ -1681,39 +1682,39 @@ protected String getTryContent(Proof proof) { /** * Makes sure that the save and loading process works. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. * @param oraclePathInBaseDirFile The oracle path. - * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof - * to save/load. - * @throws IOException Occurred Exception - * @throws ProofInputException Occurred Exception + * @param env The already executed {@link SymbolicExecutionEnvironment} which contains the proof + * to save/load. + * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, - String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) + String oraclePathInBaseDirFile, SymbolicExecutionEnvironment env) throws IOException, ProofInputException, ParserConfigurationException, SAXException, ProblemLoaderException { File javaFile = new File(baseDir, javaPathInBaseDir); assertTrue(javaFile.exists()); File tempFile = - File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); + File.createTempFile("TestProgramMethodSubsetPO", ".proof", javaFile.getParentFile()); KeYEnvironment reloadedEnv = null; SymbolicExecutionTreeBuilder reloadedBuilder = null; try { ProofSaver saver = new ProofSaver(env.getProof(), tempFile.getAbsolutePath(), - KeYConstants.INTERNAL_VERSION); + KeYConstants.INTERNAL_VERSION); assertNull(saver.save()); // Load proof from saved *.proof file reloadedEnv = KeYEnvironment.load(SymbolicExecutionJavaProfile.getDefaultInstance(), - tempFile, null, null, null, true); + tempFile, null, null, null, true); Proof reloadedProof = reloadedEnv.getLoadedProof(); assertNotSame(env.getProof(), reloadedProof); // Recreate symbolic execution tree reloadedBuilder = - new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); + new SymbolicExecutionTreeBuilder(reloadedProof, false, false, false, false, true); SymbolicExecutionUtil.initializeStrategy(reloadedBuilder); reloadedBuilder.analyse(); assertSetTreeAfterStep(reloadedBuilder, oraclePathInBaseDirFile, baseDir); @@ -1742,59 +1743,59 @@ protected void assertSaveAndReload(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? * @param maximalNumberOfExecutedSetNodesPerRun The number of executed set nodes per auto mode - * run. The whole test is executed for each defined value. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. - * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * run. The whole test is executed for each defined value. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. + * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containerTypeName, - String methodFullName, String precondition, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String methodFullName, String precondition, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int[] maximalNumberOfExecutedSetNodesPerRun, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { assertNotNull(maximalNumberOfExecutedSetNodesPerRun); for (int j : maximalNumberOfExecutedSetNodesPerRun) { SymbolicExecutionEnvironment env = doSETTest(baseDir, - javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, j, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); + javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, j, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } } @@ -1803,57 +1804,57 @@ protected void doSETTest(File baseDir, String javaPathInBaseDir, String containe * Executes method doTest * and disposes the created {@link SymbolicExecutionEnvironment}. * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, - String containerTypeName, String methodFullName, String precondition, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String containerTypeName, String methodFullName, String precondition, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, - oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, - includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, simplifyConditions); + doSETTest(baseDir, javaPathInBaseDir, containerTypeName, methodFullName, precondition, + oraclePathInBaseDirFile, includeConstraints, includeVariables, includeCallStack, + includeReturnValues, maximalNumberOfExecutedSetNodes, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, simplifyConditions); env.dispose(); } @@ -1870,47 +1871,47 @@ protected void doSETTestAndDispose(File baseDir, String javaPathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, - String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, - boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, + String oraclePathInBaseDirFile, boolean includeConstraints, boolean includeVariables, + boolean includeCallStack, boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { SymbolicExecutionEnvironment env = - doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, - includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, - useOperationContracts, useLoopInvariants, blockTreatmentContract, - nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, - variablesAreOnlyComputedFromUpdates, false, true); + doSETTest(baseDir, proofFilePathInBaseDir, oraclePathInBaseDirFile, includeConstraints, + includeVariables, includeCallStack, includeReturnValues, mergeBranchConditions, + useOperationContracts, useLoopInvariants, blockTreatmentContract, + nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, usePrettyPrinting, + variablesAreOnlyComputedFromUpdates, false, true); if (env != null) { env.dispose(); } @@ -1929,47 +1930,47 @@ protected void doSETTestAndDispose(File baseDir, String proofFilePathInBaseDir, *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param proofFilePathInBaseDir The path to the proof file inside the base directory. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param proofFilePathInBaseDir The path to the proof file inside the base directory. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String proofFilePathInBaseDir, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String proofFilePathInBaseDir, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { boolean originalOneStepSimplification = isOneStepSimplificationEnabled(null); SymbolicExecutionEnvironment env; @@ -1980,26 +1981,26 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } // Make sure that the correct taclet options are defined. setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution env = createSymbolicExecutionEnvironment(baseDir, proofFilePathInBaseDir, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, - usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, - simplifyConditions); + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, useUnicode, + usePrettyPrinting, variablesAreOnlyComputedFromUpdates, truthValueEvaluationEnabled, + simplifyConditions); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); return env; } finally { // Restore original options @@ -2020,49 +2021,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param containerTypeName The java class to test. - * @param methodFullName The method to test. - * @param precondition An optional precondition. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param containerTypeName The java class to test. + * @param methodFullName The method to test. + * @param precondition An optional precondition. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String containerTypeName, final String methodFullName, - String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, - boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, - int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, - boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) + String javaPathInBaseDir, String containerTypeName, final String methodFullName, + String precondition, String oraclePathInBaseDirFile, boolean includeConstraints, + boolean includeVariables, boolean includeCallStack, boolean includeReturnValues, + int maximalNumberOfExecutedSetNodes, boolean mergeBranchConditions, + boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; @@ -2076,23 +2077,23 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = setDefaultTacletOptions(baseDir, javaPathInBaseDir, - containerTypeName, methodFullName); + containerTypeName, methodFullName); setOneStepSimplificationEnabled(null, true); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, precondition, mergeBranchConditions, useOperationContracts, - useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, - aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, precondition, mergeBranchConditions, useOperationContracts, + useLoopInvariants, blockTreatmentContract, nonExecutionBranchHidingSideProofs, + aliasChecks, useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore original options @@ -2114,49 +2115,49 @@ protected SymbolicExecutionEnvironment doSETTest(Fi *
  • Compare created symbolic execution tree with oracle model
  • * * - * @param baseDir The base directory which contains test and oracle file. - * @param javaPathInBaseDir The path to the java file inside the base directory. - * @param baseContractName The name of the contract. - * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. - * @param includeConstraints Include constraints? - * @param includeVariables Include variables? - * @param includeCallStack Include call stack? - * @param includeReturnValues Include method return values? - * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. - * @param mergeBranchConditions Merge branch conditions? - * @param useOperationContracts Use operation contracts? - * @param useLoopInvariants Use loop invariants? - * @param blockTreatmentContract Block contracts or expand otherwise? - * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by - * side proofs, {@code false} do not hide execution branch labels. - * @param aliasChecks Do alias checks? - * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode - * characters. - * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty - * printing. + * @param baseDir The base directory which contains test and oracle file. + * @param javaPathInBaseDir The path to the java file inside the base directory. + * @param baseContractName The name of the contract. + * @param oraclePathInBaseDirFile The path to the oracle file inside the base directory. + * @param includeConstraints Include constraints? + * @param includeVariables Include variables? + * @param includeCallStack Include call stack? + * @param includeReturnValues Include method return values? + * @param maximalNumberOfExecutedSetNodes The number of executed set nodes per auto mode run. + * @param mergeBranchConditions Merge branch conditions? + * @param useOperationContracts Use operation contracts? + * @param useLoopInvariants Use loop invariants? + * @param blockTreatmentContract Block contracts or expand otherwise? + * @param nonExecutionBranchHidingSideProofs {@code true} hide non execution branch labels by + * side proofs, {@code false} do not hide execution branch labels. + * @param aliasChecks Do alias checks? + * @param useUnicode {@code true} use unicode characters, {@code false} do not use unicode + * characters. + * @param usePrettyPrinting {@code true} use pretty printing, {@code false} do not use pretty + * printing. * @param variablesAreOnlyComputedFromUpdates {@code true} {@link IExecutionVariable} are only - * computed from updates, {@code false} {@link IExecutionVariable}s are computed - * according to the type structure of the visible memory. - * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, - * {@code false} truth value evaluation is disabled. - * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify - * conditions. + * computed from updates, {@code false} {@link IExecutionVariable}s are computed + * according to the type structure of the visible memory. + * @param truthValueEvaluationEnabled {@code true} truth value evaluation is enabled, + * {@code false} truth value evaluation is disabled. + * @param simplifyConditions {@code true} simplify conditions, {@code false} do not simplify + * conditions. * @return The tested {@link SymbolicExecutionEnvironment}. - * @throws ProofInputException Occurred Exception - * @throws IOException Occurred Exception + * @throws ProofInputException Occurred Exception + * @throws IOException Occurred Exception * @throws ParserConfigurationException Occurred Exception - * @throws SAXException Occurred Exception - * @throws ProblemLoaderException Occurred Exception + * @throws SAXException Occurred Exception + * @throws ProblemLoaderException Occurred Exception */ protected SymbolicExecutionEnvironment doSETTest(File baseDir, - String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, - boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, - boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, - boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, - boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, - boolean simplifyConditions) throws ProofInputException, IOException, + String javaPathInBaseDir, String baseContractName, String oraclePathInBaseDirFile, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues, int maximalNumberOfExecutedSetNodes, + boolean mergeBranchConditions, boolean useOperationContracts, boolean useLoopInvariants, + boolean blockTreatmentContract, boolean nonExecutionBranchHidingSideProofs, + boolean aliasChecks, boolean useUnicode, boolean usePrettyPrinting, + boolean variablesAreOnlyComputedFromUpdates, boolean truthValueEvaluationEnabled, + boolean simplifyConditions) throws ProofInputException, IOException, ParserConfigurationException, SAXException, ProblemLoaderException { Map originalTacletOptions = null; try { @@ -2167,22 +2168,22 @@ protected SymbolicExecutionEnvironment doSETTest(Fi File oracleFile = new File(baseDir, oraclePathInBaseDirFile); if (!CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY) { assertTrue(oracleFile.exists(), - "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); + "Oracle file does not exist. Set \"CREATE_NEW_ORACLE_FILES_IN_TEMP_DIRECTORY\" to true to create an oracle file."); } assertTrue(maximalNumberOfExecutedSetNodes >= 1); // Make sure that the correct taclet options are defined. originalTacletOptions = - setDefaultTacletOptions(javaPathInBaseDir, baseContractName); + setDefaultTacletOptions(javaPathInBaseDir, baseContractName); // Create proof environment for symbolic execution SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, - mergeBranchConditions, useOperationContracts, useLoopInvariants, - blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, - useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, - truthValueEvaluationEnabled, simplifyConditions); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, baseContractName, + mergeBranchConditions, useOperationContracts, useLoopInvariants, + blockTreatmentContract, nonExecutionBranchHidingSideProofs, aliasChecks, + useUnicode, usePrettyPrinting, variablesAreOnlyComputedFromUpdates, + truthValueEvaluationEnabled, simplifyConditions); internalDoSETTest(oracleFile, env, oraclePathInBaseDirFile, - maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, - includeCallStack, includeReturnValues); + maximalNumberOfExecutedSetNodes, includeConstraints, includeVariables, + includeCallStack, includeReturnValues); return env; } finally { // Restore taclet options @@ -2194,15 +2195,15 @@ protected SymbolicExecutionEnvironment doSETTest(Fi * Internal test method */ private void internalDoSETTest(File oracleFile, - SymbolicExecutionEnvironment env, - String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, - boolean includeConstraints, boolean includeVariables, boolean includeCallStack, - boolean includeReturnValues) + SymbolicExecutionEnvironment env, + String oraclePathInBaseDirFile, int maximalNumberOfExecutedSetNodes, + boolean includeConstraints, boolean includeVariables, boolean includeCallStack, + boolean includeReturnValues) throws IOException, ProofInputException, ParserConfigurationException, SAXException { // Set stop condition to stop after a number of detected symbolic execution tree nodes // instead of applied rules ExecutedSymbolicExecutionTreeNodesStopCondition stopCondition = - new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); + new ExecutedSymbolicExecutionTreeNodesStopCondition(maximalNumberOfExecutedSetNodes); env.getProof().getSettings().getStrategySettings() .setCustomApplyStrategyStopCondition(stopCondition); int nodeCount; @@ -2218,11 +2219,12 @@ private void internalDoSETTest(File oracleFile, // Update symbolic execution tree env.getBuilder().analyse(); // Make sure that not to many set nodes are executed - Map executedSetNodesPerGoal = stopCondition.getExectuedSetNodesPerGoal(); + Map executedSetNodesPerGoal = + stopCondition.getExectuedSetNodesPerGoal(); for (Integer value : executedSetNodesPerGoal.values()) { assertNotNull(value); assertTrue(value <= maximalNumberOfExecutedSetNodes, - value + " is not less equal to " + maximalNumberOfExecutedSetNodes); + value + " is not less equal to " + maximalNumberOfExecutedSetNodes); } } catch (InterruptedException e) { throw new RuntimeException(e); @@ -2230,36 +2232,36 @@ private void internalDoSETTest(File oracleFile, } while (stopCondition.wasSetNodeExecuted() && nodeCount != env.getProof().countNodes()); // Create new oracle file if required in a temporary directory createOracleFile(env.getBuilder().getStartNode(), oraclePathInBaseDirFile, - includeConstraints, includeVariables, includeCallStack, includeReturnValues); + includeConstraints, includeVariables, includeCallStack, includeReturnValues); // Read oracle file ExecutionNodeReader reader = new ExecutionNodeReader(); IExecutionNode oracleRoot = reader.read(oracleFile); assertNotNull(oracleRoot); // Make sure that the created symbolic execution tree matches the expected one. assertExecutionNodes(oracleRoot, env.getBuilder().getStartNode(), includeVariables, - includeCallStack, false, includeReturnValues, includeConstraints); + includeCallStack, false, includeReturnValues, includeConstraints); } /** * Ensures that the default taclet options are defined. * * @param javaPathInBaseDir The path in the base directory to the java file. - * @param baseContractName The name of the contract to prove. + * @param baseContractName The name of the contract to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(String javaPathInBaseDir, - String baseContractName) + String baseContractName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, - baseContractName, - false, false, false, - false, false, false, - false, false, false, - false, false); + createSymbolicExecutionEnvironment(testCaseDirectory, javaPathInBaseDir, + baseContractName, + false, false, false, + false, false, false, + false, false, false, + false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2268,26 +2270,26 @@ public static Map setDefaultTacletOptions(String javaPathInBaseD /** * Ensures that the default taclet options are defined. * - * @param baseDir The base directory which contains the java file. + * @param baseDir The base directory which contains the java file. * @param javaPathInBaseDir The path in the base directory to the java file. * @param containerTypeName name of the type where the method is implemented/declared - * @param methodFullName The method to prove. + * @param methodFullName The method to prove. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ public static Map setDefaultTacletOptions(File baseDir, - String javaPathInBaseDir, - String containerTypeName, - String methodFullName) + String javaPathInBaseDir, + String containerTypeName, + String methodFullName) throws ProblemLoaderException, ProofInputException { if (!SymbolicExecutionUtil.isChoiceSettingInitialised()) { SymbolicExecutionEnvironment env = - createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, - methodFullName, - null, false, false, false, - false, false, false, false, - false, false, false); + createSymbolicExecutionEnvironment(baseDir, javaPathInBaseDir, containerTypeName, + methodFullName, + null, false, false, false, + false, false, false, false, + false, false, false); env.dispose(); } return setDefaultTacletOptions(); @@ -2296,19 +2298,19 @@ public static Map setDefaultTacletOptions(File baseDir, /** * Ensures that the default taclet options are defined. * - * @param javaFile The java file to load. + * @param javaFile The java file to load. * @param containerTypeName The type name which provides the target. - * @param targetName The target to proof. + * @param targetName The target to proof. * @return The original settings which are overwritten. * @throws ProblemLoaderException Occurred Exception. - * @throws ProofInputException Occurred Exception. + * @throws ProofInputException Occurred Exception. */ @SuppressWarnings("unused") public static Map setDefaultTacletOptionsForTarget(File javaFile, - String containerTypeName, final String targetName) + String containerTypeName, final String targetName) throws ProblemLoaderException, ProofInputException { return HelperClassForTests.setDefaultTacletOptionsForTarget(javaFile, containerTypeName, - targetName); + targetName); } /** @@ -2342,14 +2344,14 @@ public static void restoreTacletOptions(Map options) { protected ITermProgramVariableCollectorFactory createNewProgramVariableCollectorFactory( final SymbolicExecutionBreakpointStopCondition breakpointParentStopCondition) { return services -> new TermProgramVariableCollectorKeepUpdatesForBreakpointconditions( - services, breakpointParentStopCondition); + services, breakpointParentStopCondition); } /** * Makes sure that two {@link Term}s are equal. * * @param expected The expected {@link Term}. - * @param actual The actual {@link Term}. + * @param actual The actual {@link Term}. */ protected void assertTerm(Term expected, Term actual) { if (expected != null) { @@ -2369,7 +2371,7 @@ protected void assertTerm(Term expected, Term actual) { * Checks if one-step simplification is enabled in the given {@link Proof}. * * @param proof The {@link Proof} to read from or {@code null} to return the general settings - * value. + * value. * @return {@code true} one step simplification is enabled, {@code false} if disabled. */ public static boolean isOneStepSimplificationEnabled(Proof proof) { @@ -2379,9 +2381,9 @@ public static boolean isOneStepSimplificationEnabled(Proof proof) { /** * Defines if one-step simplification is enabled in general and within the {@link Proof}. * - * @param proof The optional {@link Proof}. + * @param proof The optional {@link Proof}. * @param enabled {@code true} use one-step simplification, {@code false} do not use one-step - * simplification. + * simplification. */ public static void setOneStepSimplificationEnabled(Proof proof, boolean enabled) { HelperClassForTests.setOneStepSimplificationEnabled(proof, enabled); diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java index 29a34424d09..e466b3e4876 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/AbstractProofControl.java @@ -564,7 +564,8 @@ public void startAndWaitForAutoMode(Proof proof) throws InterruptedException { * {@inheritDoc} */ @Override - public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException { + public void startAndWaitForAutoMode(Proof proof, ImmutableList goals) + throws InterruptedException { startAutoMode(proof, goals); waitWhileAutoMode(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java index 48dda5aa1f3..00a423b76c5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/DefaultProofControl.java @@ -3,6 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.control; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + import de.uka.ilkd.key.logic.PosInOccurrence; import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; @@ -16,10 +19,8 @@ import de.uka.ilkd.key.prover.impl.ApplyStrategy; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; import de.uka.ilkd.key.util.ProofStarter; -import org.key_project.util.collection.ImmutableList; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; +import org.key_project.util.collection.ImmutableList; /** * The default implementation of {@link ProofControl}. @@ -45,12 +46,12 @@ public class DefaultProofControl extends AbstractProofControl { /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. + * to all started {@link ApplyStrategy} instances. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener) { + DefaultUserInterfaceControl defaultProverTaskListener) { super(defaultProverTaskListener); this.ui = ui; } @@ -58,21 +59,21 @@ public DefaultProofControl(UserInterfaceControl ui, /** * Constructor. * - * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. + * @param ui The {@link UserInterfaceControl} in which this {@link ProofControl} is used. * @param defaultProverTaskListener The default {@link ProverTaskListener} which will be added - * to all started {@link ApplyStrategy} instances. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * to all started {@link ApplyStrategy} instances. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. */ public DefaultProofControl(UserInterfaceControl ui, - DefaultUserInterfaceControl defaultProverTaskListener, - RuleCompletionHandler ruleCompletionHandler) { + DefaultUserInterfaceControl defaultProverTaskListener, + RuleCompletionHandler ruleCompletionHandler) { super(defaultProverTaskListener, ruleCompletionHandler); this.ui = ui; } @Override public synchronized void startAutoMode(Proof proof, ImmutableList goals, - ProverTaskListener ptl) { + ProverTaskListener ptl) { if (!isInAutoMode()) { autoModeThread = new AutoModeThread(proof, goals, ptl); autoModeThread.start(); @@ -121,7 +122,7 @@ public void run() { fireAutoModeStarted(new ProofEvent(proof)); ProofStarter starter = ptl != null ? new ProofStarter( - new CompositePTListener(getDefaultProverTaskListener(), ptl), false) + new CompositePTListener(getDefaultProverTaskListener(), ptl), false) : new ProofStarter(getDefaultProverTaskListener(), false); starter.init(proof); if (goals != null) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java index dc2936d64e7..c791034caa9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java @@ -3,6 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.control; +import java.io.File; +import java.util.*; +import java.util.function.Consumer; + import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.abstraction.KeYJavaType; @@ -21,11 +25,8 @@ import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.util.KeYTypeUtil; import de.uka.ilkd.key.util.Pair; -import org.key_project.util.collection.ImmutableSet; -import java.io.File; -import java.util.*; -import java.util.function.Consumer; +import org.key_project.util.collection.ImmutableSet; /** * Instances of this class are used to collect and access all relevant information for verification @@ -67,7 +68,7 @@ public class KeYEnvironment { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig) { @@ -77,11 +78,11 @@ public KeYEnvironment(U ui, InitConfig initConfig) { /** * Constructor * - * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. + * @param ui The {@link UserInterfaceControl} in which the {@link Proof} is loaded. * @param initConfig The loaded project. */ public KeYEnvironment(U ui, InitConfig initConfig, Proof loadedProof, - Pair proofScript, ReplayResult replayResult) { + Pair proofScript, ReplayResult replayResult) { this.ui = ui; this.initConfig = initConfig; this.loadedProof = loadedProof; @@ -180,15 +181,15 @@ public Proof createProof(ProofOblInput input) throws ProofInputException { * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. + * @param location The location to load. + * @param classPaths The class path entries to use. * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param includes Optional includes to consider. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes) + List classPaths, File bootClassPath, List includes) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, false); } @@ -197,103 +198,103 @@ public static KeYEnvironment load(File location, * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(File location, - List classPaths, File bootClassPath, List includes, - RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + RuleCompletionHandler ruleCompletionHandler) throws ProblemLoaderException { return load(null, location, classPaths, bootClassPath, includes, null, - ruleCompletionHandler, false); + ruleCompletionHandler, false); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as - * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file - * will be used for new proofs. + * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file + * will be used for new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, null, null, - forceNewProfileOfNewProofs); + forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { return load(profile, location, classPaths, bootClassPath, includes, poPropertiesToForce, - ruleCompletionHandler, - null, forceNewProfileOfNewProofs); + ruleCompletionHandler, + null, forceNewProfileOfNewProofs); } /** * Loads the given location and returns all required references as {@link KeYEnvironment}. The * {@code MainWindow} is not involved in the whole process. * - * @param profile The {@link Profile} to use. - * @param location The location to load. - * @param classPaths The class path entries to use. - * @param bootClassPath The boot class path to use. - * @param includes Optional includes to consider. - * @param poPropertiesToForce Some optional PO {@link Properties} to force. - * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. - * @param callbackProofLoaded An optional callback (called when the proof is loaded, before - * replay) + * @param profile The {@link Profile} to use. + * @param location The location to load. + * @param classPaths The class path entries to use. + * @param bootClassPath The boot class path to use. + * @param includes Optional includes to consider. + * @param poPropertiesToForce Some optional PO {@link Properties} to force. + * @param ruleCompletionHandler An optional {@link RuleCompletionHandler}. + * @param callbackProofLoaded An optional callback (called when the proof is loaded, before + * replay) * @param forceNewProfileOfNewProofs {@code} true * {@code AbstractProblemLoader.profileOfNewProofs} will be used as {@link Profile} of - * new proofs, {@code false} {@link Profile} specified by problem file will be used for - * new proofs. + * new proofs, {@code false} {@link Profile} specified by problem file will be used for + * new proofs. * @return The {@link KeYEnvironment} which contains all references to the loaded location. * @throws ProblemLoaderException Occurred Exception */ public static KeYEnvironment load(Profile profile, File location, - List classPaths, File bootClassPath, List includes, - Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, - Consumer callbackProofLoaded, - boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { + List classPaths, File bootClassPath, List includes, + Properties poPropertiesToForce, RuleCompletionHandler ruleCompletionHandler, + Consumer callbackProofLoaded, + boolean forceNewProfileOfNewProofs) throws ProblemLoaderException { DefaultUserInterfaceControl ui = new DefaultUserInterfaceControl(ruleCompletionHandler); AbstractProblemLoader loader = ui.load(profile, location, classPaths, bootClassPath, - includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); + includes, poPropertiesToForce, forceNewProfileOfNewProofs, callbackProofLoaded); InitConfig initConfig = loader.getInitConfig(); return new KeYEnvironment<>(ui, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); } public static KeYEnvironment load(File keyFile) @@ -335,9 +336,11 @@ public List getAvailableContracts() { Set kjts = getJavaInfo().getAllKeYJavaTypes(); for (KeYJavaType type : kjts) { if (!KeYTypeUtil.isLibraryClass(type)) { - ImmutableSet targets = getSpecificationRepository().getContractTargets(type); + ImmutableSet targets = + getSpecificationRepository().getContractTargets(type); for (IObserverFunction target : targets) { - ImmutableSet contracts = getSpecificationRepository().getContracts(type, target); + ImmutableSet contracts = + getSpecificationRepository().getContracts(type, target); for (Contract contract : contracts) { proofContracts.add(contract); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java index f30b7bb97d1..3b5971cbb72 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/ProofControl.java @@ -123,7 +123,7 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * * @param proof The {@link Proof} to start auto mode of. */ - default void startAutoMode(Proof proof) { startAutoMode(proof, proof.openEnabledGoals());} + default void startAutoMode(Proof proof) { startAutoMode(proof, proof.openEnabledGoals()); } /** * Starts the auto mode for the given {@link Proof} and the given {@link Goal}s. @@ -158,7 +158,8 @@ void selectedBuiltInRule(Goal goal, BuiltInRule rule, PosInOccurrence pos, * @param proof The {@link Proof} to start auto mode and to wait for. * @param goals The {@link Goal}s to close. */ - void startAndWaitForAutoMode(Proof proof, ImmutableList goals) throws InterruptedException; + void startAndWaitForAutoMode(Proof proof, ImmutableList goals) + throws InterruptedException; /** * Starts the auto mode for the given proof which must be contained in this user interface and diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java index 29b9579f640..476d4ef1cb9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFacade.java @@ -18,7 +18,8 @@ public class ProofMacroFacade { private static ProofMacroFacade INSTANCE; public static ProofMacroFacade instance() { - if (INSTANCE == null) INSTANCE = new ProofMacroFacade(); + if (INSTANCE == null) + INSTANCE = new ProofMacroFacade(); return INSTANCE; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java index ebe8d366f00..962228f3ca8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/ProofMacroFinishedInfo.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.macros; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java index 44a26161832..8414e89e769 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/ProofScriptCommandFacade.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.macros.scripts; -import de.uka.ilkd.key.smt.IllegalNumberException; import java.util.Collection; import java.util.HashMap; @@ -25,7 +24,8 @@ public ProofScriptCommandFacade() { } public static ProofScriptCommandFacade instance() { - if(INSTANCE == null) INSTANCE = new ProofScriptCommandFacade(); + if (INSTANCE == null) + INSTANCE = new ProofScriptCommandFacade(); return INSTANCE; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java index 6198a8b88d9..67415ae80fd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java @@ -774,7 +774,7 @@ public List getAvailableRules() { if (just == null) { continue; // do not break system because of this } - s.add(app.taclet()); //TODO not good + s.add(app.taclet()); // TODO not good } return s; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 95ba46fe7be..9676dc91980 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.proof; +import java.util.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -24,15 +25,13 @@ import de.uka.ilkd.key.rule.RuleApp; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.util.Pair; + import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.collection.ImmutableSet; import org.key_project.util.lookup.Lookup; -import java.util.*; -import java.util.stream.Stream; - import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -128,7 +127,7 @@ public class Node implements Iterable { * taclet with an addrule section on this node, then these taclets are stored in this list */ private ImmutableSet localIntroducedRules = - DefaultImmutableSet.nil(); + DefaultImmutableSet.nil(); /** * Holds the undo methods for the information added by rules to the {@code Goal.strategyInfos}. @@ -459,7 +458,7 @@ List getLeaves() { /** * @return an iterator for the leaves of the subtree below this node. The computation is called - * at every call! + * at every call! */ public Iterator leavesIterator() { return new NodeIterator(getLeaves().iterator()); @@ -504,7 +503,7 @@ public Node child(int i) { /** * @param child a child of this node. * @return the number of the node child, if it is a child of this node (starting - * with 0), -1 otherwise + * with 0), -1 otherwise */ public int getChildNr(Node child) { int res = 0; @@ -544,16 +543,16 @@ public StringBuffer getUniqueTacletId() { * Helper for {@link #toString()} * * @param prefix needed to keep track if a line has to be printed - * @param tree the tree representation we want to add this subtree " @param preEnumeration the - * enumeration of the parent without the last number + * @param tree the tree representation we want to add this subtree " @param preEnumeration the + * enumeration of the parent without the last number * @param postNr the last number of the parents enumeration - * @param maxNr the number of nodes at this level - * @param ownNr the place of this node at this level + * @param maxNr the number of nodes at this level + * @param ownNr the place of this node at this level * @return the string representation of this node. */ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumeration, - int postNr, int maxNr, int ownNr) { + int postNr, int maxNr, int ownNr) { Iterator childrenIt = childrenIterator(); // Some constants String frontIndent = (maxNr > 1 ? " " : ""); @@ -604,7 +603,7 @@ private StringBuffer toString(String prefix, StringBuffer tree, String preEnumer while (childrenIt.hasNext()) { childId++; childrenIt.next().toString(prefix, tree, newEnumeration, newPostNr, children.size(), - childId); + childId); } return tree; @@ -661,7 +660,7 @@ public String name() { * this node. * * @return true iff the parent of this node has this node as child and this condition holds also - * for the own children. + * for the own children. */ public boolean sanityCheckDoubleLinks() { if (!root()) { @@ -788,7 +787,7 @@ public Iterator iterator() { * Retrieves a user-defined data. * * @param service the class for which the data were registered - * @param any class + * @param any class * @return null or the previous data * @see #register(Object, Class) */ @@ -806,7 +805,7 @@ public T lookup(Class service) { /** * Register a user-defined data in this node info. * - * @param obj an object to be registered + * @param obj an object to be registered * @param service the key under it should be registered * @param */ @@ -817,9 +816,9 @@ public void register(T obj, Class service) { /** * Remove a previous registered user-defined data. * - * @param obj registered object + * @param obj registered object * @param service the key under which the data was registered - * @param arbitray object + * @param arbitray object */ public void deregister(T obj, Class service) { if (userData != null) { diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java index 21f2fbc3674..04333491df3 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/njml/ContractLoadingTests.java @@ -3,28 +3,31 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.speclang.njml; +import java.io.File; +import java.util.stream.Stream; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.init.ProofInputException; import de.uka.ilkd.key.proof.io.ProblemLoaderException; import de.uka.ilkd.key.util.HelperClassForTests; + import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.util.stream.Stream; - public class ContractLoadingTests { public static final File EXAMPLES_DIR = new File("../key.ui/examples/"); static Stream files() { return Stream.of( - new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"), - new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"), - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"), - new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java") - ).map(Arguments::of); + new File(EXAMPLES_DIR, "heap/vstte10_01_SumAndMax/src/SumAndMax.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1658/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/java/Test.java"), + new File(HelperClassForTests.TESTCASE_DIRECTORY, "specMath/bigint/Test.java")) + .map(Arguments::of); } @ParameterizedTest @@ -33,9 +36,11 @@ void issues1717() throws ProblemLoaderException, ProofInputException { File javaFile = new File(HelperClassForTests.TESTCASE_DIRECTORY, "issues/1717/UnderscoreZero.java"); Assumptions.assumeTrue(javaFile.exists()); - ProofManagementApi file = KeYApi.loadProof(javaFile); - Assertions.assertTrue(file.getProofContracts().size() > 0); - var proof = file.startProof(file.getProofContracts().get(0)); + + KeYEnvironment env = KeYEnvironment.load(javaFile); + Assertions.assertFalse(env.getAvailableContracts().isEmpty()); + var proof = + env.createProof(env.getAvailableContracts().get(0).createProofObl(env.getInitConfig())); Assertions.assertNotNull(proof); } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java index 85a85b65df1..3d9c18f83f7 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/Example.java @@ -1,10 +1,8 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -14,9 +12,15 @@ import java.util.Enumeration; import java.util.List; import java.util.Properties; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * This class wraps a {@link java.io.File} and has a special {@link #toString()} method only using the + * This class wraps a {@link java.io.File} and has a special {@link #toString()} method only using + * the * short file name w/o path. *

    * Used for displaying files in the examples list w/o prefix @@ -139,12 +143,12 @@ public String toString() { public void addToTreeModel(DefaultTreeModel model) { DefaultMutableTreeNode node = - findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); + findChild((DefaultMutableTreeNode) model.getRoot(), getPath(), 0); node.add(new DefaultMutableTreeNode(this)); } private DefaultMutableTreeNode findChild(DefaultMutableTreeNode root, String[] path, - int from) { + int from) { if (from == path.length) { return root; } @@ -166,7 +170,7 @@ public boolean hasProof() { } private static StringBuilder extractDescription(File file, StringBuilder sb, - Properties properties) { + Properties properties) { try (BufferedReader r = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) { String line; boolean emptyLineSeen = false; @@ -193,4 +197,4 @@ private static StringBuilder extractDescription(File file, StringBuilder sb, } return sb; } -} \ No newline at end of file +} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java index a80815bbe03..24c539bf86f 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ProofMacroWorker.java @@ -3,6 +3,12 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; +import javax.swing.*; + import de.uka.ilkd.key.control.InteractionListener; import de.uka.ilkd.key.core.InterruptListener; import de.uka.ilkd.key.core.KeYMediator; @@ -16,15 +22,10 @@ import de.uka.ilkd.key.prover.ProverTaskListener; import de.uka.ilkd.key.prover.TaskStartedInfo; import de.uka.ilkd.key.prover.impl.DefaultTaskStartedInfo; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.swing.*; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; - /** * The Class ProofMacroWorker is a swing worker for the application of proof macros. *

    @@ -40,7 +41,7 @@ public class ProofMacroWorker extends SwingWorker * goals under the current pio, selection remains where it was. */ private static final boolean SELECT_GOAL_AFTER_MACRO = - Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); + Boolean.parseBoolean(System.getProperty("key.macro.selectGoalAfter", "true")); /** * The {@link Node} to start macro at. @@ -75,13 +76,13 @@ public class ProofMacroWorker extends SwingWorker /** * Instantiates a new proof macro worker. * - * @param node the {@link Node} to start macro at. - * @param macro the macro, not null + * @param node the {@link Node} to start macro at. + * @param macro the macro, not null * @param mediator the mediator, not null * @param posInOcc the position, possibly null */ public ProofMacroWorker(Node node, ProofMacro macro, KeYMediator mediator, - PosInOccurrence posInOcc) { + PosInOccurrence posInOcc) { assert macro != null; assert mediator != null; this.node = node; @@ -98,7 +99,7 @@ protected ProofMacroFinishedInfo doInBackground() { Proof selectedProof = node.proof(); info = ProofMacroFinishedInfo.getDefaultInfo(macro, selectedProof); ptl.taskStarted( - new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); + new DefaultTaskStartedInfo(TaskStartedInfo.TaskKind.Macro, macro.getName(), 0)); try { synchronized (macro) { info = macro.applyTo(mediator.getUI(), node, posInOcc, ptl); @@ -144,7 +145,7 @@ protected void done() { } protected void emitProofMacroFinished(Node node, ProofMacro macro, PosInOccurrence posInOcc, - ProofMacroFinishedInfo info) { + ProofMacroFinishedInfo info) { interactionListeners.forEach((l) -> l.runMacro(node, macro, posInOcc, info)); } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java index 2b8a53215d5..d3bfa1a769e 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/RunAllProofsAction.java @@ -24,16 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.awt.event.ActionEvent; -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - /** * This class provides an action for KeY UI which runs a set of specified proof files automatically. * The intent of this class is to have a massive test feature for the quality assurance of the KeY @@ -83,7 +73,7 @@ public class RunAllProofsAction extends MainWindowAction { @NonNull private List loadFiles() throws IOException { LOGGER.info("Use 'export {}=<...>' to set the input file for {}.", ENV_VARIABLE, - getClass().getSimpleName()); + getClass().getSimpleName()); InputStream stream; if (RUN_ALL_PROOFS_UI == null) { @@ -97,7 +87,7 @@ private List loadFiles() throws IOException { } try (BufferedReader in = - new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { return in.lines().filter(it -> !it.startsWith("#") && !it.trim().isEmpty()) .map(it -> (it.startsWith("/") ? new File(it) : new File(exampleDir, it)) .getAbsoluteFile()) @@ -120,7 +110,7 @@ public RunAllProofsAction(MainWindow mainWindow) { setName("Run all proofs"); setTooltip( - "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); + "Open and run a pre-defined set of proofs for GUI testing. Enabled with KeY debug flag"); } @Override @@ -136,7 +126,7 @@ public void actionPerformed(ActionEvent e) { ui.reportStatus(this, "Run: " + absFile); LOGGER.info("Run: {}", absFile); ProblemLoader problemLoader = - ui.getProblemLoader(absFile, null, null, null, getMediator()); + ui.getProblemLoader(absFile, null, null, null, getMediator()); problemLoader.runSynchronously(); LOGGER.info("Loaded: {}", absFile); diff --git a/keyext.api.doc/src/main/java/DocGen.java b/keyext.api.doc/src/main/java/DocGen.java index 36aed393607..8ab51393898 100644 --- a/keyext.api.doc/src/main/java/DocGen.java +++ b/keyext.api.doc/src/main/java/DocGen.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Comparator; @@ -47,9 +50,9 @@ private void printHeader() { } private void endpoints(Metamodel.Endpoint endpoint) { - //out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); - //out.println(getJavaDoc(typeDeclaration)); - //out.println("\n"); + // out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); + // out.println(getJavaDoc(typeDeclaration)); + // out.println("\n"); var direction = ""; if (endpoint instanceof Metamodel.ServerRequest sr) @@ -91,9 +94,9 @@ private void printType(Metamodel.Type type) { } ``` """.formatted(type.name(), - ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) - .map(it -> "\t%s : %s".formatted(it.name(), it.type())) - .collect(Collectors.joining("\n")))); + ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) + .map(it -> "\t%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining("\n")))); } if (type instanceof Metamodel.EnumType et) { @@ -101,89 +104,87 @@ private void printType(Metamodel.Type type) { ``` enum %s { %s } ``` - """.formatted(type.name(), String.join(", ", et.values()) - )); + """.formatted(type.name(), String.join(", ", et.values()))); out.format(type.documentation()); } out.format(type.documentation()); out.println(); } - /* - private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ - var annotationExpr = m.getAnnotationByName("JsonNotification").or( - () -> m.getAnnotationByName("JsonRequest")) - .orElseThrow(); - - var segment = getJsonSegment(td) + "/"; - String name = ""; - - if (annotationExpr.isMarkerAnnotationExpr()) { - name = m.getNameAsString(); - } else if (annotationExpr.isSingleMemberAnnotationExpr()) { - var sma = annotationExpr.asSingleMemberAnnotationExpr(); - name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); - } else { - var ne = annotationExpr.asNormalAnnotationExpr(); - for (MemberValuePair pair : ne.getPairs()) { - switch (pair.getName().asString()) { - case "value": - name = pair.getValue().asLiteralStringValueExpr().getValue(); - break; - case "useSegment": - if (!pair.getValue().asBooleanLiteralExpr().getValue()) { - segment = ""; - } - } - } - } - return segment + name; - } - - @Nonnull - private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ - if (typeDeclaration.getJavadoc().isPresent()) { - final var javadoc = typeDeclaration.getJavadoc().get(); - return javadoc.getDescription().toText() - + "\n\n" - + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) - .collect(Collectors.joining("\n")); - } - return ""; - } - - private static String type (MethodDeclaration method){ - if (method.getAnnotationByName("JsonNotification").isPresent()) - return "notification"; - if (method.getAnnotationByName("JsonRequest").isPresent()) - return "request"; - return ""; - } - - private static boolean isExported (MethodDeclaration method){ - return method.getAnnotationByName("JsonNotification").isPresent() - || method.getAnnotationByName("JsonRequest").isPresent(); - } - - private void printHeader () { - out.format("# KeY-API%n%n"); - } - - private void printFooter () { - } - - /* - private static boolean hasJsonSegment(TypeDeclaration it) { - return it.getAnnotationByName("JsonSegment").isPresent(); - } - - private static String getJsonSegment(TypeDeclaration it) { - var ae = it.getAnnotationByName("JsonSegment").get(); - return ae.asSingleMemberAnnotationExpr().getMemberValue() - .asLiteralStringValueExpr().getValue(); - } + * private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ + * var annotationExpr = m.getAnnotationByName("JsonNotification").or( + * () -> m.getAnnotationByName("JsonRequest")) + * .orElseThrow(); + * + * var segment = getJsonSegment(td) + "/"; + * String name = ""; + * + * if (annotationExpr.isMarkerAnnotationExpr()) { + * name = m.getNameAsString(); + * } else if (annotationExpr.isSingleMemberAnnotationExpr()) { + * var sma = annotationExpr.asSingleMemberAnnotationExpr(); + * name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); + * } else { + * var ne = annotationExpr.asNormalAnnotationExpr(); + * for (MemberValuePair pair : ne.getPairs()) { + * switch (pair.getName().asString()) { + * case "value": + * name = pair.getValue().asLiteralStringValueExpr().getValue(); + * break; + * case "useSegment": + * if (!pair.getValue().asBooleanLiteralExpr().getValue()) { + * segment = ""; + * } + * } + * } + * } + * return segment + name; + * } + * + * @Nonnull + * private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ + * if (typeDeclaration.getJavadoc().isPresent()) { + * final var javadoc = typeDeclaration.getJavadoc().get(); + * return javadoc.getDescription().toText() + * + "\n\n" + * + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) + * .collect(Collectors.joining("\n")); + * } + * return ""; + * } + * + * private static String type (MethodDeclaration method){ + * if (method.getAnnotationByName("JsonNotification").isPresent()) + * return "notification"; + * if (method.getAnnotationByName("JsonRequest").isPresent()) + * return "request"; + * return ""; + * } + * + * private static boolean isExported (MethodDeclaration method){ + * return method.getAnnotationByName("JsonNotification").isPresent() + * || method.getAnnotationByName("JsonRequest").isPresent(); + * } + * + * private void printHeader () { + * out.format("# KeY-API%n%n"); + * } + * + * private void printFooter () { + * } + * + * + * /* + * private static boolean hasJsonSegment(TypeDeclaration it) { + * return it.getAnnotationByName("JsonSegment").isPresent(); + * } + * + * private static String getJsonSegment(TypeDeclaration it) { + * var ae = it.getAnnotationByName("JsonSegment").get(); + * return ae.asSingleMemberAnnotationExpr().getMemberValue() + * .asLiteralStringValueExpr().getValue(); + * } */ } - diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/ExtractMetaData.java index 1c6c904553e..d053b9268d3 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/ExtractMetaData.java @@ -1,10 +1,26 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; + +import de.uka.ilkd.key.proof.Proof; + import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; import com.google.gson.*; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; @@ -13,18 +29,6 @@ import org.keyproject.key.api.remoteclient.ClientApi; import sun.misc.Unsafe; -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.reflect.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Supplier; - /** * @author Alexander Weigl * @version 1 (14.10.23) @@ -51,7 +55,8 @@ public static void main(String[] args) { runGenerator("server.py", PythionGenerator.PyApiGen::new); } - private static void runGenerator(String target, Function> api) { + private static void runGenerator(String target, + Function> api) { try { var n = api.apply(keyApi); Files.writeString(Paths.get(target), n.get()); @@ -65,7 +70,8 @@ private static Gson getGson() { .setPrettyPrinting() .registerTypeAdapter(Type.class, new JsonSerializer() { @Override - public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, + JsonSerializationContext context) { JsonObject json = (JsonObject) context.serialize(src); json.addProperty("kind", src.kind()); return json; @@ -76,7 +82,8 @@ public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, JsonSerializati private static void addServerEndpoint(Method method) { var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); - if (jsonSegment == null) return; + if (jsonSegment == null) + return; var segment = jsonSegment.value(); var req = method.getAnnotation(JsonRequest.class); @@ -131,27 +138,41 @@ private static Metamodel.Type getOrFindType(Class type) { return getOrFindType(type.getTypeParameters()[0].getClass()); } - if (type == Unsafe.class || type == Class.class || type == Constructor.class || type == Proof.class) { + if (type == Unsafe.class || type == Class.class || type == Constructor.class + || type == Proof.class) { throw new IllegalStateException("Forbidden class reached!"); } - if (type == String.class) return Metamodel.BuiltinType.STRING; - if (type == Integer.class) return Metamodel.BuiltinType.INT; - if (type == Double.class) return Metamodel.BuiltinType.DOUBLE; - if (type == Long.class) return Metamodel.BuiltinType.LONG; - if (type == Character.class) return Metamodel.BuiltinType.LONG; - if (type == File.class) return Metamodel.BuiltinType.STRING; - if (type == Boolean.class) return Metamodel.BuiltinType.BOOL; - if (type == Boolean.TYPE) return Metamodel.BuiltinType.BOOL; - - if (type == Integer.TYPE) return Metamodel.BuiltinType.INT; - if (type == Double.TYPE) return Metamodel.BuiltinType.DOUBLE; - if (type == Long.TYPE) return Metamodel.BuiltinType.LONG; - if (type == Character.TYPE) return Metamodel.BuiltinType.LONG; + if (type == String.class) + return Metamodel.BuiltinType.STRING; + if (type == Integer.class) + return Metamodel.BuiltinType.INT; + if (type == Double.class) + return Metamodel.BuiltinType.DOUBLE; + if (type == Long.class) + return Metamodel.BuiltinType.LONG; + if (type == Character.class) + return Metamodel.BuiltinType.LONG; + if (type == File.class) + return Metamodel.BuiltinType.STRING; + if (type == Boolean.class) + return Metamodel.BuiltinType.BOOL; + if (type == Boolean.TYPE) + return Metamodel.BuiltinType.BOOL; + + if (type == Integer.TYPE) + return Metamodel.BuiltinType.INT; + if (type == Double.TYPE) + return Metamodel.BuiltinType.DOUBLE; + if (type == Long.TYPE) + return Metamodel.BuiltinType.LONG; + if (type == Character.TYPE) + return Metamodel.BuiltinType.LONG; System.out.println(type); var t = types.stream().filter(it -> it.name().equals(type.getSimpleName())).findFirst(); - if (t.isPresent()) return t.get(); + if (t.isPresent()) + return t.get(); var a = createType(type); types.add(a); return a; @@ -161,8 +182,8 @@ private static Metamodel.Type createType(Class type) { final var documentation = findDocumentation(type); if (type.isEnum()) return new Metamodel.EnumType(type.getSimpleName(), - Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), - documentation); + Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), + documentation); var obj = new Metamodel.ObjectType(type.getSimpleName(), new ArrayList<>(), documentation); @@ -186,7 +207,8 @@ private static String findDocumentation(Class type) { e.printStackTrace(); return ""; } - } else return ""; + } else + return ""; } private static Path findFileForType(Class type) { @@ -226,7 +248,8 @@ private static void addClientEndpoint(Method method) { } } - private static String callMethodName(String method, String segment, String userValue, boolean useSegment) { + private static String callMethodName(String method, String segment, String userValue, + boolean useSegment) { if (!useSegment) { if (userValue == null || userValue.isBlank()) { return method; @@ -243,9 +266,11 @@ private static String callMethodName(String method, String segment, String userV } private static Metamodel.Type getOrFindType(Type genericReturnType) { - if (genericReturnType instanceof Class c) return getOrFindType(c); + if (genericReturnType instanceof Class c) + return getOrFindType(c); if (genericReturnType instanceof ParameterizedType pt) { - if (Objects.equals(pt.getRawType().getTypeName(), CompletableFuture.class.getTypeName())) { + if (Objects.equals(pt.getRawType().getTypeName(), + CompletableFuture.class.getTypeName())) { return getOrFindType(pt.getActualTypeArguments()[0]); } if (Objects.equals(pt.getRawType().getTypeName(), List.class.getTypeName())) { diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/Metamodel.java index 1a868f49a06..62146f0f5ee 100644 --- a/keyext.api.doc/src/main/java/Metamodel.java +++ b/keyext.api.doc/src/main/java/Metamodel.java @@ -1,7 +1,10 @@ -import org.jspecify.annotations.NullMarked; - +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ import java.util.List; +import org.jspecify.annotations.NullMarked; + /** * @author Alexander Weigl * @version 1 (29.10.23) @@ -10,11 +13,12 @@ public class Metamodel { public record KeyApi( List endpoints, - List types - ) { + List types) { } - sealed interface Endpoint { + sealed + + interface Endpoint { String name(); String documentation(); @@ -42,55 +46,67 @@ record ClientNotification(String name, String documentation, List args } record Field(String name, /*Type*/ String type, String documentation) { - Field(String name, String type) { + + Field(String name, String type) { this(name, type, ""); } - } +} - public sealed interface Type { - default String kind() { +public sealed + + +interface Type { + default String kind() { return getClass().getSimpleName(); } - String documentation(); + String documentation(); - String name(); - } + String name(); +} - enum BuiltinType implements Type { - INT, LONG, STRING, BOOL, DOUBLE; - @Override - public String documentation() { - return "built-in data type"; - } +enum BuiltinType implements Type { + INT, LONG, STRING, BOOL, DOUBLE; + + @Override + public String documentation() { + return "built-in data type"; + } + } record ListType(Type type, String documentation) implements Type { - @Override - public String name() { - return type().name() + "[]"; - } + + @Override + public String name() { + return type().name() + "[]"; + } + } record ObjectType(String typeName, List fields, String documentation) implements Type { - @Override - public String name() { - return typeName; - } + + @Override + public String name() { + return typeName; + } + } public record EitherType(Type a, Type b, String documentation) implements Type { - @Override - public String name() { - return "either"; - } + + @Override + public String name() { + return "either"; + } + } public record EnumType(String typeName, List values, String documentation) implements Type { - @Override - public String name() { - return typeName; - } + + @Override + public String name() { + return typeName; } -} +}} diff --git a/keyext.api.doc/src/main/java/PythionGenerator.java b/keyext.api.doc/src/main/java/PythionGenerator.java index a4d2018c328..9fc222a1221 100644 --- a/keyext.api.doc/src/main/java/PythionGenerator.java +++ b/keyext.api.doc/src/main/java/PythionGenerator.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Comparator; @@ -54,11 +57,11 @@ protected String asPython(Metamodel.Type t) { if (t instanceof Metamodel.BuiltinType bt) { return switch (bt) { - case INT -> "int"; - case LONG -> "int"; - case STRING -> "str"; - case BOOL -> "bool"; - case DOUBLE -> "float"; + case INT -> "int"; + case LONG -> "int"; + case STRING -> "str"; + case BOOL -> "bool"; + case DOUBLE -> "float"; }; } return t.name(); @@ -85,19 +88,21 @@ protected void run() { import enum import abc import typing - from abc import abstractmethod + from abc import abstractmethod """); server( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ServerRequest || it instanceof Metamodel.ServerNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ServerRequest + || it instanceof Metamodel.ServerNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); client( - metamodel.endpoints() - .stream() - .filter(it -> it instanceof Metamodel.ClientRequest || it instanceof Metamodel.ClientNotification) - .sorted(Comparator.comparing(Metamodel.Endpoint::name))); + metamodel.endpoints() + .stream() + .filter(it -> it instanceof Metamodel.ClientRequest + || it instanceof Metamodel.ClientNotification) + .sorted(Comparator.comparing(Metamodel.Endpoint::name))); } @@ -113,7 +118,7 @@ private void clientEndpoint(Metamodel.Endpoint endpoint) { out.format(" @abstractmethod%n"); if (endpoint instanceof Metamodel.ClientRequest sr) { out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, - asPython(sr.returnType())); + asPython(sr.returnType())); } else { out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); } @@ -128,7 +133,7 @@ private void server(Stream sorted) { class KeyServer(ServerBase):%n def __init__(self, endpoint : LspEndpoint): super().__init__(endpoint) - + """); sorted.forEach(this::serverEndpoint); } @@ -147,13 +152,15 @@ private void serverEndpoint(Metamodel.Endpoint endpoint) { if (endpoint instanceof Metamodel.ServerRequest sr) { out.format(" def %s(self, %s) -> %s:%n", endpoint.name().replace("/", "_"), args, - asPython(sr.returnType())); + asPython(sr.returnType())); out.format(" \"\"\"%s\"\"\"%n%n", sr.documentation()); - out.format(" return self._call_sync(\"%s\", %s)".formatted(endpoint.name(), params)); + out.format( + " return self._call_sync(\"%s\", %s)".formatted(endpoint.name(), params)); } else { out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" return self._call_async(\"%s\", %s)".formatted(endpoint.name(), params)); + out.format(" return self._call_async(\"%s\", %s)".formatted(endpoint.name(), + params)); } out.println(); out.println(); @@ -183,12 +190,13 @@ protected void run() { import abc import typing from abc import abstractmethod, ABCMeta - + """); metamodel.types().forEach(this::printType); - var names = metamodel.types().stream().map(it -> "\"%s\": %s".formatted(it.name(), it.name())) - .collect(Collectors.joining(",")); + var names = + metamodel.types().stream().map(it -> "\"%s\": %s".formatted(it.name(), it.name())) + .collect(Collectors.joining(",")); out.format("KEY_DATA_CLASSES = { %s }%n%n", names); } @@ -200,10 +208,9 @@ private void printType(Metamodel.Type type) { .formatted(it.name(), asPython(it.type()), it.documentation()))); out.format("\n def __init__(self%s):%n".formatted( - ot.fields().stream() - .map(Metamodel.Field::name) - .collect(Collectors.joining(", ", ", ", "")) - )); + ot.fields().stream() + .map(Metamodel.Field::name) + .collect(Collectors.joining(", ", ", ", "")))); if (ot.fields().isEmpty()) out.format(" pass%n%n"); @@ -220,4 +227,4 @@ private void printType(Metamodel.Type type) { out.println(); } } -} \ No newline at end of file +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java index b8f61b62272..9082242ee37 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/GenericSerializer.java @@ -1,13 +1,18 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; -import com.google.gson.*; - import java.lang.reflect.Type; +import com.google.gson.*; + /** - * Stackoverflow post + * Stackoverflow + * post */ -public class GenericSerializer implements JsonSerializer /*, JsonDeserializer*/ { +public class GenericSerializer implements JsonSerializer /* , JsonDeserializer */ { private static final String CLASS_PROPERTY_NAME = "$type"; private final Gson gson; @@ -21,31 +26,31 @@ public GenericSerializer(Gson gson) { } /* - @Override - public Object deserialize(JsonElement json, Type typeOfT, - JsonDeserializationContext context) throws JsonParseException { - - Class actualClass; - if (json.isJsonObject()) { - JsonObject jsonObject = json.getAsJsonObject(); - String className = jsonObject.get(CLASS_PROPERTY_NAME).getAsString(); - try { - actualClass = Class.forName(className); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - throw new JsonParseException(e.getMessage()); - } - } else { - actualClass = typeOfT.getClass(); - } - - return gson.fromJson(json, actualClass); - } + * @Override + * public Object deserialize(JsonElement json, Type typeOfT, + * JsonDeserializationContext context) throws JsonParseException { + * + * Class actualClass; + * if (json.isJsonObject()) { + * JsonObject jsonObject = json.getAsJsonObject(); + * String className = jsonObject.get(CLASS_PROPERTY_NAME).getAsString(); + * try { + * actualClass = Class.forName(className); + * } catch (ClassNotFoundException e) { + * e.printStackTrace(); + * throw new JsonParseException(e.getMessage()); + * } + * } else { + * actualClass = typeOfT.getClass(); + * } + * + * return gson.fromJson(json, actualClass); + * } */ @Override public JsonElement serialize(Object src, Type typeOfSrc, - JsonSerializationContext context) { + JsonSerializationContext context) { JsonElement retValue = gson.toJsonTree(src); if (retValue.isJsonObject()) { retValue.getAsJsonObject().addProperty(CLASS_PROPERTY_NAME, src.getClass().getName()); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index f2a28731d3a..1e3a0539711 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -1,5 +1,18 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + import de.uka.ilkd.key.control.AbstractUserInterfaceControl; import de.uka.ilkd.key.control.DefaultUserInterfaceControl; import de.uka.ilkd.key.control.KeYEnvironment; @@ -23,11 +36,13 @@ import de.uka.ilkd.key.prover.TaskStartedInfo; import de.uka.ilkd.key.speclang.PositionedString; import de.uka.ilkd.key.util.KeYConstants; + +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSet; + import org.eclipse.lsp4j.jsonrpc.CompletableFutures; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.key_project.util.collection.ImmutableList; -import org.key_project.util.collection.ImmutableSet; import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.internal.NodeText; @@ -36,16 +51,6 @@ import org.keyproject.key.api.remoteapi.PrintOptions; import org.keyproject.key.api.remoteclient.ClientApi; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - public final class KeyApiImpl implements KeyApi { private final KeyIdentifications data = new KeyIdentifications(); @@ -74,8 +79,8 @@ public KeyApiImpl() { @Override @JsonRequest public CompletableFuture> examples() { - return CompletableFutures.computeAsync((c) -> - ExampleChooser.listExamples(ExampleChooser.lookForExamples()) + return CompletableFutures + .computeAsync((c) -> ExampleChooser.listExamples(ExampleChooser.lookForExamples()) .stream().map(ExampleDesc::from).toList()); } @@ -101,19 +106,20 @@ public CompletableFuture getVersion() { @Override public CompletableFuture> getAvailableMacros() { return CompletableFuture.completedFuture( - ProofMacroFacade.instance().getMacros().stream() - .map(ProofMacroDesc::from).toList() - ); + ProofMacroFacade.instance().getMacros().stream() + .map(ProofMacroDesc::from).toList()); } @Override public CompletableFuture> getAvailableScriptCommands() { return CompletableFuture.completedFuture( - ProofScriptCommandFacade.instance().getScriptCommands().stream().map(ProofScriptCommandDesc::from).toList()); + ProofScriptCommandFacade.instance().getScriptCommands().stream() + .map(ProofScriptCommandDesc::from).toList()); } @Override - public CompletableFuture script(ProofId proofId, String scriptLine, StreategyOptions options) { + public CompletableFuture script(ProofId proofId, String scriptLine, + StreategyOptions options) { return CompletableFuture.supplyAsync(() -> { var proof = data.find(proofId); var env = data.find(proofId.env()); @@ -129,14 +135,16 @@ public CompletableFuture script(ProofId proofId, String scriptLi } @Override - public CompletableFuture macro(ProofId proofId, String macroId, StreategyOptions options) { + public CompletableFuture macro(ProofId proofId, String macroId, + StreategyOptions options) { return CompletableFuture.supplyAsync(() -> { var proof = data.find(proofId); var env = data.find(proofId.env()); var macro = Objects.requireNonNull(ProofMacroFacade.instance().getMacro(macroId)); try { - var info = macro.applyTo(env.getUi(), proof, proof.openGoals(), null, clientListener); + var info = + macro.applyTo(env.getUi(), proof, proof.openGoals(), null, clientListener); return MacroStatistic.from(proofId, info); } catch (Exception e) { throw new RuntimeException(e); @@ -152,8 +160,8 @@ public CompletableFuture auto(ProofId proofId, StreategyOptions var env = data.find(proofId.env()); try { env.getProofControl().startAndWaitForAutoMode(proof); - //clientListener); - return null;//MacroStatistic.from(proofId, info); + // clientListener); + return null;// MacroStatistic.from(proofId, info); } catch (Exception e) { throw new RuntimeException(e); } @@ -172,7 +180,8 @@ public CompletableFuture dispose(ProofId id) { } @Override - public CompletableFuture> goals(ProofId proofId, boolean onlyOpened, boolean onlyEnabled) { + public CompletableFuture> goals(ProofId proofId, boolean onlyOpened, + boolean onlyEnabled) { return CompletableFuture.supplyAsync(() -> { var proof = data.find(proofId); if (onlyOpened && !onlyEnabled) { @@ -195,7 +204,7 @@ private List asNodeDesc(ProofId proofId, Stream nodes) { private NodeDesc asNodeDesc(ProofId proofId, Node it) { return new NodeDesc(proofId, it.serialNr(), it.getNodeInfo().getBranchLabel(), - it.getNodeInfo().getScriptRuleApplication()); + it.getNodeInfo().getScriptRuleApplication()); } @Override @@ -207,12 +216,12 @@ public CompletableFuture tree(ProofId proofId) { } private NodeDesc asNodeDescRecursive(ProofId proofId, Node root) { - final List list = root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList(); + final List list = + root.childrenStream().map(it -> asNodeDescRecursive(proofId, it)).toList(); return new NodeDesc(new NodeId(proofId, root.serialNr()), - root.getNodeInfo().getBranchLabel(), - root.getNodeInfo().getScriptRuleApplication(), - list - ); + root.getNodeInfo().getBranchLabel(), + root.getNodeInfo().getScriptRuleApplication(), + list); } @Override @@ -282,7 +291,8 @@ public CompletableFuture> contracts(EnvironmentId envId) { return CompletableFuture.supplyAsync(() -> { var env = data.find(envId); var contracts = env.getAvailableContracts(); - return contracts.stream().map(it -> ContractDesc.from(envId, env.getServices(), it)).toList(); + return contracts.stream().map(it -> ContractDesc.from(envId, env.getServices(), it)) + .toList(); }); } @@ -291,7 +301,8 @@ public CompletableFuture openContract(ContractId contractId) { return CompletableFuture.supplyAsync(() -> { var env = data.find(contractId.envId()); var contracts = env.getAvailableContracts(); - var contract = contracts.stream().filter(it -> it.id() == contractId.contractId()).findFirst(); + var contract = + contracts.stream().filter(it -> it.id() == contractId.contractId()).findFirst(); if (contract.isPresent()) { try { var proof = env.createProof(contract.get().createProofObl(env.getInitConfig())); @@ -311,7 +322,8 @@ public CompletableFuture print(NodeId nodeId, PrintOptions options var node = data.find(nodeId); var env = data.find(nodeId.proofId().env()); var notInfo = new NotationInfo(); - final var layouter = new PosTableLayouter(options.width(), options.indentation(), options.pure()); + final var layouter = + new PosTableLayouter(options.width(), options.indentation(), options.pure()); var lp = new LogicPrinter(notInfo, env.getServices(), layouter); lp.printSequent(node.sequent()); @@ -332,8 +344,9 @@ public CompletableFuture> actions(NodeTextId printId, int p var goal = proof.getOpenGoal(node); var nodeText = data.find(printId); var pis = nodeText.table().getPosInSequent(pos, filter); - return new TermActionUtil(printId, data.find(printId.nodeId().proofId().env()), pis, goal) - .getActions(); + return new TermActionUtil(printId, data.find(printId.nodeId().proofId().env()), pis, + goal) + .getActions(); }); } @@ -365,19 +378,21 @@ public CompletableFuture loadExample(String id) { KeYEnvironment env = null; try { var loader = control.load(JavaProfile.getDefaultProfile(), - ex.getObligationFile(), null, null, null, null, true, null); + ex.getObligationFile(), null, null, null, null, true, null); InitConfig initConfig = loader.getInitConfig(); env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); var envId = new EnvironmentId(env.toString()); data.register(envId, env); proof = Objects.requireNonNull(env.getLoadedProof()); var proofId = new ProofId(envId, proof.name().toString()); return data.register(proofId, proof); } catch (ProblemLoaderException e) { - if (proof != null) proof.dispose(); - if (env != null) env.dispose(); + if (proof != null) + proof.dispose(); + if (env != null) + env.dispose(); throw new RuntimeException(e); } } @@ -390,17 +405,19 @@ public CompletableFuture loadProblem(ProblemDefinition problem) { return CompletableFutures.computeAsync((c) -> { Proof proof = null; KeYEnvironment env = null; - /* var loader = control.load(JavaProfile.getDefaultProfile(), - ex.getObligationFile(), null, null, null, null, true, null); - InitConfig initConfig = loader.getInitConfig(); - - env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); - var envId = new EnvironmentId(env.toString()); - data.register(envId, env); - proof = Objects.requireNonNull(env.getLoadedProof()); - var proofId = new ProofId(envId, proof.name().toString()); - return data.register(proofId, proof);*/ + /* + * var loader = control.load(JavaProfile.getDefaultProfile(), + * ex.getObligationFile(), null, null, null, null, true, null); + * InitConfig initConfig = loader.getInitConfig(); + * + * env = new KeYEnvironment<>(control, initConfig, loader.getProof(), + * loader.getProofScript(), loader.getResult()); + * var envId = new EnvironmentId(env.toString()); + * data.register(envId, env); + * proof = Objects.requireNonNull(env.getLoadedProof()); + * var proofId = new ProofId(envId, proof.name().toString()); + * return data.register(proofId, proof); + */ return null; }); @@ -415,18 +432,20 @@ public CompletableFuture loadKey(String content) { final var tempFile = File.createTempFile("json-rpc-", ".key"); Files.writeString(tempFile.toPath(), content); var loader = control.load(JavaProfile.getDefaultProfile(), - tempFile, null, null, null, null, true, null); + tempFile, null, null, null, null, true, null); InitConfig initConfig = loader.getInitConfig(); env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); var envId = new EnvironmentId(env.toString()); data.register(envId, env); proof = Objects.requireNonNull(env.getLoadedProof()); var proofId = new ProofId(envId, proof.name().toString()); return data.register(proofId, proof); } catch (ProblemLoaderException | IOException e) { - if (proof != null) proof.dispose(); - if (env != null) env.dispose(); + if (proof != null) + proof.dispose(); + if (env != null) + env.dispose(); throw new RuntimeException(e); } }); @@ -444,16 +463,16 @@ public CompletableFuture> load(LoadParams params) KeYEnvironment env = null; try { var loader = control.load(JavaProfile.getDefaultProfile(), - params.keyFile(), - params.classPath(), - params.bootClassPath(), - params.includes(), - null, - true, - null); + params.keyFile(), + params.classPath(), + params.bootClassPath(), + params.includes(), + null, + true, + null); InitConfig initConfig = loader.getInitConfig(); env = new KeYEnvironment<>(control, initConfig, loader.getProof(), - loader.getProofScript(), loader.getResult()); + loader.getProofScript(), loader.getResult()); var envId = new EnvironmentId(env.toString()); data.register(envId, env); if ((proof = env.getLoadedProof()) != null) { @@ -463,8 +482,10 @@ public CompletableFuture> load(LoadParams params) return Either.forLeft(envId); } } catch (ProblemLoaderException e) { - if (proof != null) proof.dispose(); - if (env != null) env.dispose(); + if (proof != null) + proof.dispose(); + if (env != null) + env.dispose(); throw new RuntimeException(e); } }); @@ -502,7 +523,9 @@ public void loadingStarted(AbstractProblemLoader loader) { } @Override - public void loadingFinished(AbstractProblemLoader loader, IPersistablePO.LoadedPOContainer poContainer, ProofAggregate proofList, AbstractProblemLoader.ReplayResult result) throws ProblemLoaderException { + public void loadingFinished(AbstractProblemLoader loader, + IPersistablePO.LoadedPOContainer poContainer, ProofAggregate proofList, + AbstractProblemLoader.ReplayResult result) throws ProblemLoaderException { super.loadingFinished(loader, poContainer, proofList, result); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java index f28001e8c15..2f948413e72 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/NodeTextId.java @@ -1,4 +1,4 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; - -import org.keyproject.key.api.data.KeyIdentifications.NodeId; - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java index b0491145cda..53293b35680 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/StartServer.java @@ -1,6 +1,16 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.io.*; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.concurrent.ExecutionException; +import javax.annotation.Nullable; + import com.google.gson.GsonBuilder; import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.websocket.jakarta.WebSocketLauncherBuilder; @@ -11,13 +21,6 @@ import picocli.CommandLine; import picocli.CommandLine.Option; -import javax.annotation.Nullable; -import java.io.*; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.concurrent.ExecutionException; - /** * @author Alexander Weigl * @version 1 (07.10.23) @@ -26,7 +29,7 @@ public class StartServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(StartServer.class); - //region CLI arguments + // region CLI arguments @Option(names = "--std", description = "use stdout and stdin for communication") boolean stdStreams; @Option(names = "--trace", description = "use stdout and stdin for communication") @@ -41,19 +44,21 @@ public class StartServer implements Runnable { Integer clientPort; - @Option(names = "--infile", paramLabel = "FILE or PIPE", description = "read from named pipe or file") + @Option(names = "--infile", paramLabel = "FILE or PIPE", + description = "read from named pipe or file") @Nullable File inFile; - @Option(names = "--outfile", paramLabel = "FILE or PIPE", description = "write to named pipe or file") + @Option(names = "--outfile", paramLabel = "FILE or PIPE", + description = "write to named pipe or file") File outFile; - @Option(names = {"-h", "--help"}, usageHelp = true, description = "display a help message") + @Option(names = { "-h", "--help" }, usageHelp = true, description = "display a help message") boolean helpRequested = false; @Option(names = "--websocket") boolean websocket = false; - //endregion + // endregion public static void main(String[] args) { new CommandLine(new StartServer()).execute(args); @@ -159,12 +164,11 @@ public static Launcher launch(OutputStream out, InputStream in, KeyAp .validateMessages(true); launcherBuilder.configureGson(StartServer::configureJson); - //if (localServices != null && !localServices.isEmpty()) + // if (localServices != null && !localServices.isEmpty()) launcherBuilder.setLocalService(keyApi); - //if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) + // if (remoteInterfaces != null && !remoteInterfaces.isEmpty()) launcherBuilder.setRemoteInterface(ClientApi.class); return launcherBuilder.create(); } } - diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java index 31714a361d7..c65a93d677a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -1,5 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.control.ProofControl; import de.uka.ilkd.key.logic.Name; @@ -9,56 +16,53 @@ import de.uka.ilkd.key.pp.PosInSequent; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.*; -import org.jspecify.annotations.NonNull; + import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; + +import org.jspecify.annotations.NonNull; import org.keyproject.key.api.data.KeyIdentifications; import org.keyproject.key.api.data.KeyIdentifications.NodeTextId; import org.keyproject.key.api.data.TermActionDesc; import org.keyproject.key.api.data.TermActionKind; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - /** * @author Alexander Weigl * @version 1 (29.10.23) */ public class TermActionUtil { private static final Set CLUTTER_RULESETS = - Set.of(new Name("notHumanReadable"), - new Name("obsolete"), - new Name("pullOutQuantifierAll"), - new Name("pullOutQuantifierEx")); + Set.of(new Name("notHumanReadable"), + new Name("obsolete"), + new Name("pullOutQuantifierAll"), + new Name("pullOutQuantifierEx")); private static final Set CLUTTER_RULES = Set.of( - new Name("cut_direct_r"), - new Name("cut_direct_l"), - new Name("case_distinction_r"), - new Name("case_distinction_l"), - new Name("local_cut"), - new Name("commute_and_2"), - new Name("commute_or_2"), - new Name("boxToDiamond"), - new Name("pullOut"), - new Name("typeStatic"), - new Name("less_is_total"), - new Name("less_zero_is_total"), - new Name("applyEqReverse"), + new Name("cut_direct_r"), + new Name("cut_direct_l"), + new Name("case_distinction_r"), + new Name("case_distinction_l"), + new Name("local_cut"), + new Name("commute_and_2"), + new Name("commute_or_2"), + new Name("boxToDiamond"), + new Name("pullOut"), + new Name("typeStatic"), + new Name("less_is_total"), + new Name("less_zero_is_total"), + new Name("applyEqReverse"), - // the following are used for drag'n'drop interactions - new Name("eqTermCut"), - new Name("instAll"), - new Name("instEx") - ); + // the following are used for drag'n'drop interactions + new Name("eqTermCut"), + new Name("instAll"), + new Name("instEx")); private static final Set FILTER_SCRIPT_COMMANDS = Set.of( - "exit", - "leave", - "javascript", - "skip", - "macro", - "rule", - "script"); + "exit", + "leave", + "javascript", + "skip", + "macro", + "rule", + "script"); private final PosInSequent pos; private final Goal goal; @@ -67,7 +71,8 @@ public class TermActionUtil { private final List actions = new ArrayList<>(1024); private final NodeTextId nodeTextId; - public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment env, @NonNull PosInSequent pos, @NonNull Goal goal) { + public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment env, + @NonNull PosInSequent pos, @NonNull Goal goal) { this.pos = pos; this.goal = goal; this.nodeTextId = nodeTextId; @@ -75,8 +80,10 @@ public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment ProofControl c = env.getUi().getProofControl(); final ImmutableList builtInRules = c.getBuiltInRule(goal, occ); for (ProofMacro macro : ProofMacroFacade.instance().getMacros()) { - var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "macro:" + macro.getScriptCommandName()); - TermActionDesc ta = new TermActionDesc(id, macro.getName(), macro.getDescription(), macro.getCategory(), TermActionKind.Macro); + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), + "macro:" + macro.getScriptCommandName()); + TermActionDesc ta = new TermActionDesc(id, macro.getName(), macro.getDescription(), + macro.getCategory(), TermActionKind.Macro); add(ta); } ImmutableList findTaclet = c.getFindTaclet(goal, occ); @@ -86,16 +93,18 @@ public TermActionUtil(@NonNull NodeTextId nodeTextId, @NonNull KeYEnvironment for (TacletApp tacletApp : find) { - var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "find:" + tacletApp.rule()); + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), + "find:" + tacletApp.rule()); TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), - tacletApp.rule().toString(), "", TermActionKind.Taclet); + tacletApp.rule().toString(), "", TermActionKind.Taclet); add(ta); } for (TacletApp tacletApp : nofind) { - var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), "nofind:" + tacletApp.rule()); + var id = new KeyIdentifications.TermActionId(nodeTextId.nodeId(), pos.toString(), + "nofind:" + tacletApp.rule()); TermActionDesc ta = new TermActionDesc(id, tacletApp.rule().displayName(), - tacletApp.rule().toString(), "", TermActionKind.Taclet); + tacletApp.rule().toString(), "", TermActionKind.Taclet); add(ta); } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 67871cec674..53cd4cec09c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -1,49 +1,54 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.adapters; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; + +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.macros.ProofMacro; + import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.macros.ProofMacro; import org.keyproject.key.api.data.MacroDescription; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Type; - /** * @author Alexander Weigl * @version 1 (14.10.23) */ public class KeyAdapter { - //private final BiMap> map = HashBiMap.create(1024); - //private final TypeAdapter adaptor; + // private final BiMap> map = HashBiMap.create(1024); + // private final TypeAdapter adaptor; public KeyAdapter(GsonBuilder gson) { gson.registerTypeAdapter(File.class, new FileTypeAdapter()); - //gson.registerTypeAdapter(Function.class, new FunctionSerializer()); - //gson.registerTypeAdapter(ProofMacro.class, new MacroSerializer()); + // gson.registerTypeAdapter(Function.class, new FunctionSerializer()); + // gson.registerTypeAdapter(ProofMacro.class, new MacroSerializer()); } /* - //translating entities to identification strings - public void insert(Identifiable p) { - var id = p.identification(); - if (!map.containsKey(id)) { - map.put(id, new WeakReference<>(p)); - } - } - - public Object find(String id) { - return map.get(id).get(); - } - //endregion - */ + * //translating entities to identification strings + * public void insert(Identifiable p) { + * var id = p.identification(); + * if (!map.containsKey(id)) { + * map.put(id, new WeakReference<>(p)); + * } + * } + * + * public Object find(String id) { + * return map.get(id).get(); + * } + * //endregion + */ static class MacroSerializer implements JsonSerializer { @Override - public JsonElement serialize(ProofMacro src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(ProofMacro src, Type typeOfSrc, + JsonSerializationContext context) { return context.serialize(MacroDescription.from(src)); } } @@ -62,7 +67,8 @@ public File read(JsonReader in) throws IOException { static class FunctionSerializer implements JsonSerializer { @Override - public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(Function src, Type typeOfSrc, + JsonSerializationContext context) { var obj = new JsonObject(); obj.add("name", context.serialize(src.name().toString())); obj.add("skolemConstant", context.serialize(src.isSkolemConstant())); @@ -76,7 +82,8 @@ public JsonElement serialize(Function src, Type typeOfSrc, JsonSerializationCont public static class ThrowableAdapter implements JsonSerializer { @Override - public JsonElement serialize(Throwable src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(Throwable src, Type typeOfSrc, + JsonSerializationContext context) { var obj = new JsonObject(); obj.add("$class", context.serialize(src.getClass().getSimpleName())); obj.add("message", context.serialize(src.getMessage())); @@ -85,16 +92,22 @@ public JsonElement serialize(Throwable src, Type typeOfSrc, JsonSerializationCon } } - /*class IdentifiableTypeAdapter implements JsonSerializer, JsonDeserializer { - @Override - public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - return (Identifiable) find(json.getAsString()); - } - - @Override - public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerializationContext context) { - insert(src); - return context.serialize(src.identification()); - } - }*/ + /* + * class IdentifiableTypeAdapter implements JsonSerializer, + * JsonDeserializer { + * + * @Override + * public Identifiable deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext + * context) throws JsonParseException { + * return (Identifiable) find(json.getAsString()); + * } + * + * @Override + * public JsonElement serialize(Identifiable src, Type typeOfSrc, JsonSerializationContext + * context) { + * insert(src); + * return context.serialize(src.identification()); + * } + * } + */ } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java index bbc28eec1ec..522f32d9b3b 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/package-info.java @@ -4,4 +4,4 @@ * @author Alexander Weigl * @version 1 (14.10.23) */ -package org.keyproject.key.api.adapters; \ No newline at end of file +package org.keyproject.key.api.adapters; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java index 531bc2fb56d..b6a363a6f6e 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ContractDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.java.Services; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java index 1868871c0e3..3b7238f676e 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -1,9 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import de.uka.ilkd.key.logic.op.Function; - import java.util.List; +import de.uka.ilkd.key.logic.op.Function; + /** * @author Alexander Weigl * @version 1 (15.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java index 6d66823142a..3f512c76fbd 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/KeyIdentifications.java @@ -1,16 +1,20 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; +import java.lang.ref.WeakReference; +import java.util.Objects; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import org.jspecify.annotations.NonNull; import org.keyproject.key.api.internal.NodeText; -import java.lang.ref.WeakReference; -import java.util.Objects; - /** * @author Alexander Weigl * @version 1 (29.10.23) @@ -19,27 +23,31 @@ public class KeyIdentifications { private final BiMap mapEnv = HashBiMap.create(16); public KeyEnvironmentContainer getContainer(EnvironmentId environmentId) { - return Objects.requireNonNull(mapEnv.get(environmentId), "Could not find environment for id" + environmentId); + return Objects.requireNonNull(mapEnv.get(environmentId), + "Could not find environment for id" + environmentId); } public ProofContainer getContainer(ProofId proofId) { return Objects.requireNonNull(getContainer(proofId.env()).mapProof.get(proofId), - "Could not find proof for id" + proofId); + "Could not find proof for id" + proofId); } public KeYEnvironment find(EnvironmentId envid) { - return Objects.requireNonNull(getContainer(envid).env.get(), "Environment was removed by gc"); + return Objects.requireNonNull(getContainer(envid).env.get(), + "Environment was removed by gc"); } @NonNull public Proof find(ProofId proofId) { - return Objects.requireNonNull(getContainer(proofId).wProof.get(), "Could not find a proof for id " + proofId); + return Objects.requireNonNull(getContainer(proofId).wProof.get(), + "Could not find a proof for id " + proofId); } @NonNull public NodeText find(NodeTextId nodeTextId) { - return Objects.requireNonNull(getContainer(nodeTextId.nodeId().proofId()).mapGoalText.get(nodeTextId), - "Could not find a print-out with the id " + nodeTextId); + return Objects.requireNonNull( + getContainer(nodeTextId.nodeId().proofId()).mapGoalText.get(nodeTextId), + "Could not find a print-out with the id " + nodeTextId); } public void dispose(NodeTextId nodeTextId) { @@ -54,7 +62,8 @@ public void dispose(ProofId id) { } public Node find(NodeId nodeId) { - @NonNull Proof p = find(nodeId.proofId); + @NonNull + Proof p = find(nodeId.proofId); var opt = p.findAny(it -> it.serialNr() == nodeId.nodeId()); return Objects.requireNonNull(opt, "Could not find node with serialNr " + nodeId.nodeId); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java index 85ec900cd57..6d0a47c9a3f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/LoadParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import java.io.File; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java index 0274bc38b30..fc2a8ba0e95 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroDescription.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacro; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java index b0c2397d1f3..6825f99a90c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/MacroStatistic.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacroFinishedInfo; @@ -6,10 +9,9 @@ * @author Alexander Weigl * @version 1 (13.10.23) */ -public record MacroStatistic(KeyIdentifications.ProofId proofId, String macroId, boolean cancelled, int appliedRules, +public record MacroStatistic(KeyIdentifications.ProofId proofId, String macroId, int appliedRules, int closedGoals) { public static MacroStatistic from(KeyIdentifications.ProofId proofId, ProofMacroFinishedInfo info) { - return new MacroStatistic(proofId, info.getMacro().getName(), info.isCancelled(), - info.getAppliedRules(), info.getClosedGoals()); + return new MacroStatistic(proofId, info.getMacro().getName(), info.getAppliedRules(), info.getClosedGoals()); } } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java index eda5e693f64..cd306e53816 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeDesc.java @@ -1,9 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import org.jspecify.annotations.Nullable; - import java.util.List; +import org.jspecify.annotations.Nullable; + /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java index 333b24f1c73..df4eb11f82f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/NodeTextDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java index 640c25371d6..dbb0e899496 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/PredicateDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java index d952ea3a654..be69d976fc7 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProblemDefinition.java @@ -1,10 +1,13 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import org.jspecify.annotations.Nullable; - import java.util.List; +import org.jspecify.annotations.Nullable; + /** * @author Alexander Weigl * @version 1 (15.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java index 31981c61beb..f1faea9cf12 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofMacroDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.ProofMacro; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java index f6eef733d08..0f086d8f936 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/ProofScriptCommandDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import de.uka.ilkd.key.macros.scripts.ProofScriptCommand; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java index 66df02ee6b0..797f8ccb16f 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -1,9 +1,12 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; -import de.uka.ilkd.key.logic.sort.Sort; - import java.util.List; +import de.uka.ilkd.key.logic.sort.Sort; + /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java index b73ee35b7b5..ea804f0562b 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/StreategyOptions.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java index b27ac08a279..d9c619f4dea 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; import org.keyproject.key.api.data.KeyIdentifications.TermActionId; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java index cc7d9aec71a..0a371aa48e4 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionKind.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java index 7f8c9564aa9..99a258f79d4 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TraceValue.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; public enum TraceValue { diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java index 213bb6b9dbe..7f8509df70c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TreeNodeDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.data; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java index 5750fea944d..84898829e9a 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/internal/NodeText.java @@ -1,8 +1,9 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.internal; import de.uka.ilkd.key.pp.InitialPositionTable; -import de.uka.ilkd.key.pp.PositionTable; -import de.uka.ilkd.key.proof.Node; /** * @author Alexander Weigl diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java index e84a0152760..dc8fb6362c6 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/EnvApi.java @@ -1,5 +1,11 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.ContractDesc; @@ -7,9 +13,6 @@ import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.SortDesc; -import java.util.List; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java index 6c52dfd39aa..5f19f881e9d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleApi.java @@ -1,12 +1,14 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.gui.Example; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; - import java.util.List; import java.util.concurrent.CompletableFuture; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; +import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; + @JsonSegment("examples") public interface ExampleApi { @JsonRequest("list") diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java index c0091943899..e2f00758a72 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ExampleDesc.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; import de.uka.ilkd.key.gui.Example; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java index 959ed91570c..68a9e263708 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/GoalApi.java @@ -1,14 +1,17 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.data.NodeTextDesc; import org.keyproject.key.api.data.*; import org.keyproject.key.api.data.KeyIdentifications.*; - -import java.util.List; -import java.util.concurrent.CompletableFuture; +import org.keyproject.key.api.data.NodeTextDesc; /** * @author Alexander Weigl diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java index 56a166f9af7..a94b35967af 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/KeyApi.java @@ -1,7 +1,11 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; /** * The combined interface that is provided by KeY. */ -public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, GoalApi, EnvApi, ProofLoadApi{ +public interface KeyApi extends ExampleApi, MetaApi, ServerManagement, ProofApi, ProofTreeApi, + GoalApi, EnvApi, ProofLoadApi { } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java index f101a47f16a..ea2c8174a58 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/MetaApi.java @@ -1,14 +1,17 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.ProofMacroDesc; import org.keyproject.key.api.data.ProofScriptCommandDesc; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import org.keyproject.key.api.data.KeyIdentifications.*; - @JsonSegment("meta") public interface MetaApi { @JsonRequest("version") diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java index 6555b2a16fb..4144c9e6877 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/PrintOptions.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; /** diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java index e496b7a4d38..8d0fc27154d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofApi.java @@ -1,25 +1,31 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import de.uka.ilkd.key.proof.Statistics; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.keyproject.key.api.data.KeyIdentifications.*; import org.keyproject.key.api.data.MacroStatistic; import org.keyproject.key.api.data.NodeDesc; import org.keyproject.key.api.data.StreategyOptions; -import java.util.List; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) */ public interface ProofApi { @JsonRequest - CompletableFuture script(ProofId proof, String scriptLine, StreategyOptions options); + CompletableFuture script(ProofId proof, String scriptLine, + StreategyOptions options); @JsonRequest - CompletableFuture macro(ProofId proof, String macroId, StreategyOptions options); + CompletableFuture macro(ProofId proof, String macroId, + StreategyOptions options); @JsonRequest CompletableFuture auto(ProofId proof, StreategyOptions options); diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java index 9ffedadf57d..2b5f5e78187 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofLoadApi.java @@ -1,19 +1,20 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; -import de.uka.ilkd.key.control.KeYEnvironment; -import de.uka.ilkd.key.proof.Proof; +import java.util.concurrent.CompletableFuture; + import de.uka.ilkd.key.proof.io.ProblemLoaderException; + import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import org.keyproject.key.api.data.KeyIdentifications; import org.keyproject.key.api.data.KeyIdentifications.EnvironmentId; import org.keyproject.key.api.data.KeyIdentifications.ProofId; import org.keyproject.key.api.data.LoadParams; import org.keyproject.key.api.data.ProblemDefinition; -import java.util.concurrent.CompletableFuture; - /** * Functionalities for loading proofs either from a built-in example, or from a set of files. * @@ -24,6 +25,7 @@ public interface ProofLoadApi { /** * I am not sure whether this is helpful. Mainly a feature for testing?! + * * @param id * @return */ @@ -53,5 +55,6 @@ public interface ProofLoadApi { * @throws ProblemLoaderException if something went wrong */ @JsonRequest - CompletableFuture> load(LoadParams params) throws ProblemLoaderException; -} \ No newline at end of file + CompletableFuture> load(LoadParams params) + throws ProblemLoaderException; +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java index d3225919d63..cd4aa88b146 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ProofTreeApi.java @@ -1,14 +1,17 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.List; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.KeyIdentifications.ProofId; import org.keyproject.key.api.data.KeyIdentifications.TreeNodeId; import org.keyproject.key.api.data.TreeNodeDesc; -import java.util.List; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java index 00e85b9e021..bcbff9a04ff 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/ServerManagement.java @@ -1,12 +1,15 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteapi; +import java.util.concurrent.CompletableFuture; + import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; import org.keyproject.key.api.data.TraceValue; -import java.util.concurrent.CompletableFuture; - /** * @author Alexander Weigl * @version 1 (13.10.23) @@ -15,9 +18,15 @@ public interface ServerManagement { /** * Shutdown Request (:leftwards_arrow_with_hook:) - * The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit notification until they have received a response from the shutdown request. + * The shutdown request is sent from the client to the server. It asks the server to shut down, + * but to not exit (otherwise the response might not be delivered correctly to the client). + * There is a separate exit notification that asks the server to exit. Clients must not send any + * notifications other than exit or requests to a server to which they have sent a shutdown + * request. Clients should also wait with sending the exit notification until they have received + * a response from the shutdown request. *

    - * If a server receives requests after a shutdown request those requests should error with InvalidRequest. + * If a server receives requests after a shutdown request those requests should error with + * InvalidRequest. *

    * Request: *

    @@ -33,7 +42,8 @@ public interface ServerManagement { /** * Exit Notification (:arrow_right:) - * A notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1. + * A notification to ask the server to exit its process. The server should exit with success + * code 0 if the shutdown request has been received before; otherwise with error code 1. *

    * Notification: *

    diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java index ca086eae72f..fe34e79927e 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ClientApi.java @@ -1,14 +1,18 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nullable; + import de.uka.ilkd.key.prover.TaskFinishedInfo; import de.uka.ilkd.key.prover.TaskStartedInfo; + import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; -import javax.annotation.Nullable; -import java.util.concurrent.CompletableFuture; - @JsonSegment("client") public interface ClientApi { @JsonNotification @@ -16,9 +20,13 @@ public interface ClientApi { /** * LogTrace Notification (:arrow_left:) - * A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. + * A notification to log the trace of the server’s execution. The amount and content of these + * notifications depends on the current trace configuration. If trace is 'off', the server + * should not send any logTrace notification. If trace is 'messages', the server should not add + * the 'verbose' field in the LogTraceParams. *

    - * $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. + * $/logTrace should be used for systematic trace reporting. For single debugging messages, the + * server should send window/logMessage notifications. *

    * Notification: *

    @@ -27,11 +35,12 @@ public interface ClientApi { */ @JsonNotification void logTrace(LogTraceParams params); - //region Window + // region Window /** * ShowMessage Notification (:arrow_left:) - * The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. + * The show message notification is sent from a server to a client to ask the client to display + * a particular message in the user interface. *

    * Notification: *

    @@ -45,7 +54,9 @@ public interface ClientApi { /** * ShowMessage Request (:arrow_right_hook:) - * The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client. + * The show message request is sent from a server to a client to ask the client to display a + * particular message in the user interface. In addition to the show message notification the + * request allows to pass actions and to wait for an answer from the client. */ @JsonRequest @Nullable @@ -56,7 +67,8 @@ public interface ClientApi { * Show Document Request (:arrow_right_hook:) * New in version 3.16.0 *

    - * The show document request is sent from a server to a client to ask the client to display a particular resource referenced by a URI in the user interface. + * The show document request is sent from a server to a client to ask the client to display a + * particular resource referenced by a URI in the user interface. *

    * property path (optional): window.showDocument * property type: ShowDocumentClientCapabilities defined as follows: @@ -66,7 +78,9 @@ public interface ClientApi { void taskFinished(TaskFinishedInfo info); + void taskProgress(int position); + void taskStarted(TaskStartedInfo info); - //endregion + // endregion } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java index 7ae00a584e7..d1ae6245f0d 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogMessageParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; record LogMessageParams( diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java index b5995ff5220..9328544be6c 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/LogTraceParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; import org.eclipse.lsp4j.jsonrpc.validation.NonNull; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java index df586cac66d..79e94cc39bb 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageActionItem.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public record MessageActionItem( diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java index cb8c20dd311..8564f136f36 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/MessageType.java @@ -1,28 +1,31 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public enum MessageType { - Unused, - /** - * An error message. - */ - Error, - /** - * A warning message. - */ - Warning, - /** - * An information message. - */ - Info, - /** - * A log message. - */ - Log, - /** - * A debug message. - * - * @proposed - * @since 3.18.0 - */ - Debug - } + Unused, + /** + * An error message. + */ + Error, + /** + * A warning message. + */ + Warning, + /** + * An information message. + */ + Info, + /** + * A log message. + */ + Log, + /** + * A debug message. + * + * @proposed + * @since 3.18.0 + */ + Debug +} diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java index 17502b1a910..1e3050bbfde 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; import de.uka.ilkd.key.pp.Range; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java index b91a100858a..bb455cbebd5 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowDocumentResult.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public record ShowDocumentResult( diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java index 9bf22a6f552..5b0a6fc0286 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; public record ShowMessageParams( @@ -10,5 +13,5 @@ public record ShowMessageParams( * The actual message. */ String message) { - + } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java index 49e662c6524..6dcc7164acc 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/ShowMessageRequestParams.java @@ -1,3 +1,6 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api.remoteclient; import java.util.List; diff --git a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java index b275265b6c7..5f2335e5ef3 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/SimpleClient.java @@ -1,11 +1,15 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nullable; + import de.uka.ilkd.key.prover.TaskFinishedInfo; import de.uka.ilkd.key.prover.TaskStartedInfo; -import org.keyproject.key.api.remoteclient.*; -import javax.annotation.Nullable; -import java.util.concurrent.CompletableFuture; +import org.keyproject.key.api.remoteclient.*; class SimpleClient implements ClientApi { diff --git a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java index 5e0c87e06f5..9e7869bdfaa 100644 --- a/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java +++ b/keyext.api/src/test/java/org/keyproject/key/api/TestRpc.java @@ -1,13 +1,8 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package org.keyproject.key.api; -import org.eclipse.lsp4j.jsonrpc.Launcher; -import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.keyproject.key.api.remoteapi.KeyApi; -import org.keyproject.key.api.remoteclient.ClientApi; - import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; @@ -18,6 +13,14 @@ import java.util.logging.Level; import java.util.logging.Logger; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.keyproject.key.api.remoteapi.KeyApi; +import org.keyproject.key.api.remoteclient.ClientApi; + public class TestRpc { private Future clientListening, serverListening; private KeyApi keyApi; diff --git a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java index 5d7647eaf34..5c02f2ba138 100644 --- a/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java +++ b/keyext.exploration/src/test/java/org/key_project/exploration/ProofExplorationServiceTest.java @@ -3,6 +3,8 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.exploration; +import java.io.File; + import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.nparser.KeyIO; @@ -10,13 +12,13 @@ import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; + +import org.key_project.util.collection.ImmutableList; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.key_project.util.collection.ImmutableList; - -import java.io.File; import static org.junit.jupiter.api.Assertions.*; @@ -83,7 +85,7 @@ public void testAdditionAntec() { assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -125,7 +127,7 @@ public void testAdditionSucc() { testAddition(withAddedTerm, justification, added, false); assertTrue(checkNodeForExplorationDataAndAction(withAddedTerm.node().parent()), - "Parent is marked as ExplorationNode and data contains Exploration Action"); + "Parent is marked as ExplorationNode and data contains Exploration Action"); assertFalse(checkNodeForExplorationDataAndAction(withAddedTerm.node())); assertFalse(checkNodeForExplorationDataAndAction(justification.node())); @@ -146,9 +148,9 @@ public void testChangeFormula() { assertSame(1, goals.size(), "Prerequisite for test"); Sequent sequent = goals.head().node().sequent(); PosInOccurrence pio = - new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); + new PosInOccurrence(sequent.succedent().get(0), PosInTerm.getTopLevel(), false); expService.applyChangeFormula(goals.head(), pio, sequent.succedent().get(0).formula(), - change); + change); ImmutableList newCreatedGoals = currentProof.openGoals(); assertEquals(2, newCreatedGoals.size(), "Two new goals created"); @@ -166,7 +168,7 @@ public void testChangeFormula() { assertNotNull(justificationBranch.node().lookup(ExplorationNodeData.class)); assertEquals(new Name("hide_right"), hideNode.getAppliedRuleApp().rule().name(), - "Hide Right was applied"); + "Hide Right was applied"); // set all goals to interactive justificationBranch.setEnabled(true); // perform proof, it has to close @@ -184,34 +186,34 @@ public void testChangeFormula() { */ private void testAddition(Goal withAddedTerm, Goal justification, Term added, boolean antec) { Semisequent semiSeqAdded = - antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfAdded = - antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); Semisequent semiSeqUntouched = - !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); + !antec ? withAddedTerm.sequent().antecedent() : withAddedTerm.sequent().succedent(); Semisequent parentSemiSeqOfUntouched = - !antec ? withAddedTerm.node().parent().sequent().antecedent() - : withAddedTerm.node().parent().sequent().succedent(); + !antec ? withAddedTerm.node().parent().sequent().antecedent() + : withAddedTerm.node().parent().sequent().succedent(); assertSame(semiSeqAdded.size(), parentSemiSeqOfAdded.size() + 1, - "The size of the added semisequent has changed"); + "The size of the added semisequent has changed"); assertEquals(semiSeqAdded.get(0).formula(), added, "Added Term is indeed added"); assertFalse(justification.isAutomatic(), "Justification branch is marked as interactive"); assertSame(semiSeqUntouched.size(), parentSemiSeqOfUntouched.size(), - "The size if untouched semisequents is the same"); + "The size if untouched semisequents is the same"); assertEquals(semiSeqUntouched, parentSemiSeqOfUntouched, - "The untouched semisequents are equal"); + "The untouched semisequents are equal"); Node parent = withAddedTerm.node().parent(); assertEquals(parent, justification.node().parent(), "Both nodes have the same parent"); assertEquals(new Name("cut"), parent.getAppliedRuleApp().rule().name(), - "The addition was inserted using the cut rule"); + "The addition was inserted using the cut rule"); } /** diff --git a/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java b/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java index 087e4c5d59f..045e315d72c 100644 --- a/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java +++ b/keyext.ui.testgen/src/main/java/de/uka/ilkd/key/gui/testgen/TGInfoDialog.java @@ -35,9 +35,12 @@ public void actionPerformed(ActionEvent e) { // This method delegates the request only to the UserInterfaceControl // which implements the functionality. No functionality is allowed in this method body! new Thread(() -> { - MainWindow.getInstance().getMediator().getUI().getProofControl() - .stopAndWaitAutoMode(); - ThreadUtilities.invokeOnEventQueue(() -> exitButton.setEnabled(true)); + try { + MainWindow.getInstance().getMediator().getUI().getProofControl() + .stopAndWaitAutoMode(); + ThreadUtilities.invokeOnEventQueue(() -> exitButton.setEnabled(true)); + } catch (InterruptedException ignore) { + } }).start(); } }; From 82ef399b7356017644cf211e9851308cc06ea439 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Fri, 21 Jun 2024 16:07:00 +0200 Subject: [PATCH 19/50] reenable sonarqube, disable the crappy things * also fix some encoding in recorder/src files --- .github/old_workflows/sonarqube.yml | 39 -------- .github/workflows/artiweb.yml | 88 ------------------ .github/workflows/code_quality.yml | 89 +------------------ .github/workflows/codeql.yml | 43 --------- .github/workflows/sonarqube.yml | 49 ++++++++++ build.gradle | 11 +++ gradle.properties | 1 + .../recoder/abstraction/IntersectionType.java | 2 +- .../java5to4/EnhancedFor2For.java | 2 +- 9 files changed, 64 insertions(+), 260 deletions(-) delete mode 100644 .github/old_workflows/sonarqube.yml delete mode 100644 .github/workflows/artiweb.yml delete mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/sonarqube.yml create mode 100644 gradle.properties diff --git a/.github/old_workflows/sonarqube.yml b/.github/old_workflows/sonarqube.yml deleted file mode 100644 index ac751f0d5a8..00000000000 --- a/.github/old_workflows/sonarqube.yml +++ /dev/null @@ -1,39 +0,0 @@ -# This workflow helps you trigger a SonarCloud analysis of your code and populates -# GitHub Code Scanning alerts with the vulnerabilities found. -name: SonarCloud analysis - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - workflow_dispatch: - -permissions: - pull-requests: read # allows SonarCloud to decorate PRs with analysis results - -jobs: - Analysis: - runs-on: ubuntu-latest - steps: - - name: Analyze with SonarCloud - # You can pin the exact commit or the version. - # uses: SonarSource/sonarcloud-github-action@de2e56b42aa84d0b1c5b622644ac17e505c9a049 - uses: SonarSource/sonarcloud-github-action@de2e56b42aa84d0b1c5b622644ac17e505c9a049 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on Sonarcloud.io, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret) - with: - args: - # Unique keys of your project and organization. You can find them in SonarCloud > Information (bottom-left menu) - # mandatory - -Dsonar.projectKey=key-main - -Dsonar.organization=keyproject - # Comma-separated paths to directories containing main source files. - #-Dsonar.sources= # optional, default is project base directory - # When you need the analysis to take place in a directory other than the one from which it was launched - #-Dsonar.projectBaseDir= # optional, default is . - # Comma-separated paths to directories containing test source files. - #-Dsonar.tests= # optional. For more info about Code Coverage, please refer to https://docs.sonarcloud.io/enriching/test-coverage/overview/ - # Adds more detail to both client and server-side analysis logs, activating DEBUG mode for the scanner, and adding client-side environment variables and system properties to the server-side log of analysis report processing. - #-Dsonar.verbose= # optional, default is false diff --git a/.github/workflows/artiweb.yml b/.github/workflows/artiweb.yml deleted file mode 100644 index ca963363cf0..00000000000 --- a/.github/workflows/artiweb.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: Artiweb Comment - -on: - workflow_run: - workflows: [Tests] - types: - - completed - -# taken from https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow -jobs: - comment: - runs-on: ubuntu-latest - steps: - - name: 'Download artifact' - id: da - uses: actions/github-script@v7 - with: - script: | - if (context.payload.workflow_run === undefined) { - core.setFailed("No workflow run found"); - } - const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - const testArtifact = allArtifacts.data.artifacts.find((artifact) => { - return artifact.name == "test-results" - }); - if (testArtifact !== undefined) { - core.info("Found test-results artifact id: " + testArtifact.id); - core.setOutput("test-artifact-id", testArtifact.id); - } else { - core.info("Artifact test-results was not found"); - } - - const numberArtifact = allArtifacts.data.artifacts.find((artifact) => { - return artifact.name == "pr-number" - }); - if (numberArtifact !== undefined) { - core.info("Found pr-number artifact id: " + numberArtifact.id); - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: numberArtifact.id, - archive_format: 'zip', - }); - let fs = require('fs'); - fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data)); - } else { - core.setFailed("Artifact pr-number was not found"); - } - - - name: 'Unzip artifact' - run: unzip pr_number.zip - - - name: 'Read pr number' - id: rpn - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - let fs = require('fs'); - let issue_number_text = fs.readFileSync('./pr_number', 'utf8'); - core.info("Found pr number \"" + issue_number_text + "\""); - core.setOutput("pr-number", issue_number_text === "" ? "" : Number(issue_number_text)); - - name: Find Comment - if: ${{ steps.rpn.outputs.pr-number != '' }} - uses: peter-evans/find-comment@v3 - id: fc - with: - issue-number: ${{ steps.rpn.outputs.pr-number }} - comment-author: 'github-actions[bot]' - body-includes: Artiweb - - - name: Create or update comment - if: ${{ steps.rpn.outputs.pr-number != '' }} - uses: peter-evans/create-or-update-comment@v4 - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ steps.rpn.outputs.pr-number }} - body: | - Thank you for your contribution. - - The test artifacts are available on [Artiweb](e8e3f762-a110-4e21-bc41-cacb5f3a3a50.ka.bw-cloud-instance.org/${{steps.rpn.outputs.pr-number}}/). - The newest artifact is [here](e8e3f762-a110-4e21-bc41-cacb5f3a3a50.ka.bw-cloud-instance.org/${{steps.rpn.outputs.pr-number}}/${{steps.da.outputs.test-artifact-id}}/). - edit-mode: replace diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index 5410a014e96..1365c36e398 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -24,21 +24,6 @@ jobs: with: arguments: -DENABLE_NULLNESS=true compileTest - - qodana: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2024.1.5 - - - uses: github/codeql-action/upload-sarif@v3 - if: success() || failure() - with: - sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json - formatting: runs-on: ubuntu-latest steps: @@ -51,76 +36,4 @@ jobs: - name: Build with Gradle uses: gradle/gradle-build-action@v3.3.2 with: - arguments: --continue spotlessCheck - - # checkstyle: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - # with: - # fetch-depth: 0 - # - run: scripts/tools/checkstyle/runIncrementalCheckstyle.sh --xml | tee report.xml - # - run: | - # npx violations-command-line -sarif sarif-report.json \ - # -v "CHECKSTYLE" "." ".*/report.xml$" "Checkstyle" \ - # -diff-to $(git merge-base HEAD origin/main) -pv false - - # - uses: github/codeql-action/upload-sarif@v3 - # if: success() || failure() - # with: - # sarif_file: sarif-report.json - - - checkstyle_new: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: 'corretto' - java-version: '21' - cache: 'gradle' - - - name: Build with Gradle - uses: gradle/gradle-build-action@v3.3.2 - with: - arguments: --continue checkstyleMainChanged - - run: | - npx violations-command-line -sarif sarif-report.json \ - -v "CHECKSTYLE" "." ".*/build/reports/checkstyle/main_diff.xml$" "Checkstyle" - - #-diff-from $(git merge-base HEAD origin/main) - # - run: python3 ./.github/printcs.py */build/reports/checkstyle/main_diff.xml - - # $(git merge-base HEAD origin/main) - - - uses: github/codeql-action/upload-sarif@v3 - if: success() || failure() - with: - sarif_file: sarif-report.json - - pmd: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: 'corretto' - java-version: '21' - cache: 'gradle' - - name: Build with Gradle - uses: gradle/gradle-build-action@v3.3.2 - with: - arguments: --continue pmdMainChanged - - # - run: python3 ./.github/printAnnotations.py */build/reports/pmd/main.xml - - - run: | - npx violations-command-line -sarif pmd-report.json \ - -v "PMD" "." ".*/build/reports/pmd/main_diff.xml$" "PMD" - - # -diff-from $(git merge-base HEAD origin/main) - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: pmd-report.json + arguments: --continue spotlessCheck \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index efdedd8caf2..00000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ "main" ] - pull_request: - branches: - - "main" - - "KeY-*" - schedule: - - cron: '21 21 * * 4' - merge_group: - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'java' ] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml new file mode 100644 index 00000000000..5749981d98f --- /dev/null +++ b/.github/workflows/sonarqube.yml @@ -0,0 +1,49 @@ +## Copied from SonarCloud + +name: SonarCloud +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] + +jobs: + build: + name: Build and analyze + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: 21 + distribution: 'zulu' + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@v3 + with: + build-scan-publish: true + build-scan-terms-of-use-url: "https://gradle.com/terms-of-service" + build-scan-terms-of-use-agree: "yes" + + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GRADLE_OPTS: "-Xmx6g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8" + run: ./gradlew --parallel --continue -DjacocoEnabled=true -x :key.core.symbolic_execution:test -x :key.core.proof_references:test classes testClasses :key.util:test jacocoTestReport sonar \ No newline at end of file diff --git a/build.gradle b/build.gradle index 935addaa9a8..487eb193e5c 100644 --- a/build.gradle +++ b/build.gradle @@ -25,8 +25,19 @@ plugins { // EISOP Checker Framework id "org.checkerframework" version "0.6.39" + + id("org.sonarqube") version "5.0.0.4638" +} + +sonar { + properties { + property "sonar.projectKey", "KeYProject_key" + property "sonar.organization", "keyproject" + property "sonar.host.url", "https://sonarcloud.io" + } } + // Configure this project for use inside IntelliJ: idea { module { diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000000..7937f1c737f --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 \ No newline at end of file diff --git a/recoder/src/main/java/recoder/abstraction/IntersectionType.java b/recoder/src/main/java/recoder/abstraction/IntersectionType.java index 49186270c8c..c3e5cc0b836 100644 --- a/recoder/src/main/java/recoder/abstraction/IntersectionType.java +++ b/recoder/src/main/java/recoder/abstraction/IntersectionType.java @@ -11,7 +11,7 @@ import recoder.service.ProgramModelInfo; /** - * Represents an intersection type, which was introduced in java 5. See JLS, 3rd edition, �4.9 for + * Represents an intersection type, which was introduced in java 5. See JLS, 3rd edition, §4.9 for * details. * * @author Tobias Gutzmann diff --git a/recoder/src/main/java/recoder/kit/transformation/java5to4/EnhancedFor2For.java b/recoder/src/main/java/recoder/kit/transformation/java5to4/EnhancedFor2For.java index 52e98bccb81..17e4f816382 100644 --- a/recoder/src/main/java/recoder/kit/transformation/java5to4/EnhancedFor2For.java +++ b/recoder/src/main/java/recoder/kit/transformation/java5to4/EnhancedFor2For.java @@ -25,7 +25,7 @@ import recoder.list.generic.ASTList; /** - * converts an enhanced for loop to an "old style" for loop. This follows JLS 3rd edition, �14.14.2. + * converts an enhanced for loop to an "old style" for loop. This follows JLS 3rd edition, §14.14.2. *

    * Currently, if given enhanced for iterates over an array, this will replace the enhanced for with * a statement block and not inline it into a possibly given statement block, yielding possibly not From f024c0736b903024dc8df961bd21622214945728 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Wed, 26 Jun 2024 16:11:29 +0200 Subject: [PATCH 20/50] fix after refactoring + spotless --- .../main/java/de/uka/ilkd/key/control/KeYEnvironment.java | 3 +-- .../src/main/java/org/keyproject/key/api/TermActionUtil.java | 2 +- .../java/org/keyproject/key/api/adapters/KeyAdapter.java | 3 ++- .../main/java/org/keyproject/key/api/data/FunctionDesc.java | 5 +++-- .../src/main/java/org/keyproject/key/api/data/SortDesc.java | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java index 18a2b12b0d5..bbc57b344ca 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/KeYEnvironment.java @@ -21,13 +21,12 @@ import de.uka.ilkd.key.proof.io.AbstractProblemLoader.ReplayResult; import de.uka.ilkd.key.proof.io.ProblemLoaderException; import de.uka.ilkd.key.proof.mgt.SpecificationRepository; - import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.util.KeYTypeUtil; -import org.key_project.util.collection.Pair; import org.key_project.util.collection.ImmutableSet; +import org.key_project.util.collection.Pair; /** * Instances of this class are used to collect and access all relevant information for verification diff --git a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java index c65a93d677a..4e121061d84 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/TermActionUtil.java @@ -9,7 +9,6 @@ import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.control.ProofControl; -import de.uka.ilkd.key.logic.Name; import de.uka.ilkd.key.logic.PosInOccurrence; import de.uka.ilkd.key.macros.ProofMacro; import de.uka.ilkd.key.macros.ProofMacroFacade; @@ -17,6 +16,7 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.*; +import org.key_project.logic.Name; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java index 53cd4cec09c..bd423049595 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/adapters/KeyAdapter.java @@ -7,9 +7,10 @@ import java.io.IOException; import java.lang.reflect.Type; -import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.macros.ProofMacro; +import org.key_project.logic.op.Function; + import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java index 3b7238f676e..d664c5a3981 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/FunctionDesc.java @@ -5,7 +5,8 @@ import java.util.List; -import de.uka.ilkd.key.logic.op.Function; +import org.key_project.logic.op.Function; + /** * @author Alexander Weigl @@ -14,7 +15,7 @@ public record FunctionDesc(String name, String sort, SortDesc retSort, List argSorts, boolean rigid, boolean unique, boolean skolemConstant) { public static FunctionDesc from(Function fn) { - return new FunctionDesc(fn.name().toString(), fn.proofToString(), + return new FunctionDesc(fn.name().toString(), fn.sort().declarationString(), SortDesc.from(fn.sort()), fn.argSorts().stream().map(SortDesc::from).toList(), fn.isRigid(), diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java index 797f8ccb16f..587803ac2e6 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/SortDesc.java @@ -5,7 +5,7 @@ import java.util.List; -import de.uka.ilkd.key.logic.sort.Sort; +import org.key_project.logic.sort.Sort; /** * @author Alexander Weigl From 8c33e8c1d397739d136106323a368deec035d527 Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Sun, 20 Oct 2024 16:12:52 +0200 Subject: [PATCH 21/50] wip --- build.gradle | 8 +- keyext.api.doc/build.gradle | 4 +- keyext.api.doc/src/main/java/DocGen.java | 190 ----------------- .../org/key_project/key/api/doc/DocGen.java | 107 ++++++++++ .../key/api/doc}/ExtractMetaData.java | 198 ++++++++++-------- .../key_project/key/api/doc}/Metamodel.java | 2 +- .../key/api/doc/PythonGenerator.java} | 22 +- .../org/keyproject/key/api/KeyApiImpl.java | 14 +- .../key/api/data/TermActionDesc.java | 25 ++- .../keyproject/key/api/data/package-info.java | 7 + .../org/keyproject/key/api/package-info.java | 7 + .../key/api/remoteapi/package-info.java | 7 + .../key/api/remoteclient/package-info.java | 7 + 13 files changed, 284 insertions(+), 314 deletions(-) delete mode 100644 keyext.api.doc/src/main/java/DocGen.java create mode 100644 keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java rename keyext.api.doc/src/main/java/{ => org/key_project/key/api/doc}/ExtractMetaData.java (61%) rename keyext.api.doc/src/main/java/{ => org/key_project/key/api/doc}/Metamodel.java (96%) rename keyext.api.doc/src/main/java/{PythionGenerator.java => org/key_project/key/api/doc/PythonGenerator.java} (93%) create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/package-info.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java create mode 100644 keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java diff --git a/build.gradle b/build.gradle index b7a41f249f6..aa60dbfd676 100644 --- a/build.gradle +++ b/build.gradle @@ -73,8 +73,8 @@ subprojects { version = rootProject.version java { - sourceCompatibility = 17 - targetCompatibility = 17 + sourceCompatibility = 22 + targetCompatibility = 22 } repositories { @@ -111,8 +111,8 @@ subprojects { tasks.withType(JavaCompile) { // Setting UTF-8 as the java source encoding. options.encoding = "UTF-8" - // Setting the release to Java 17 - options.release = 17 + // Setting the release to Java 22 + options.release = 22 } tasks.withType(Javadoc) { diff --git a/keyext.api.doc/build.gradle b/keyext.api.doc/build.gradle index 84a1789e01f..0c275f1d19e 100644 --- a/keyext.api.doc/build.gradle +++ b/keyext.api.doc/build.gradle @@ -1,5 +1,5 @@ dependencies { implementation(project(":keyext.api")) - implementation("com.github.javaparser:javaparser-core:3.25.5") - implementation("com.github.javaparser:javaparser-symbol-solver-core:3.25.5") + implementation("com.github.javaparser:javaparser-symbol-solver-core:3.26.1") + implementation("info.picocli:picocli:4.7.6") } \ No newline at end of file diff --git a/keyext.api.doc/src/main/java/DocGen.java b/keyext.api.doc/src/main/java/DocGen.java deleted file mode 100644 index 8ab51393898..00000000000 --- a/keyext.api.doc/src/main/java/DocGen.java +++ /dev/null @@ -1,190 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Comparator; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -/** - * @author Alexander Weigl - * @version 1 (29.10.23) - */ -public class DocGen implements Supplier { - private final Metamodel.KeyApi metamodel; - private PrintWriter out; - private final StringWriter target = new StringWriter(); - - public DocGen(Metamodel.KeyApi metamodel) { - this.metamodel = metamodel; - } - - @Override - public String get() { - try (var out = new PrintWriter(target)) { - this.out = out; - printHeader(); - - out.format("## Types%n"); - metamodel.types() - .stream().sorted(Comparator.comparing(Metamodel.Type::name)) - .forEach(this::printType); - - out.format("## Endpoints%n"); - metamodel.endpoints() - .stream().sorted(Comparator.comparing(Metamodel.Endpoint::name)) - .forEach(this::endpoints); - printFooter(); - } - return target.toString(); - } - - private void printFooter() { - - } - - private void printHeader() { - - - } - - private void endpoints(Metamodel.Endpoint endpoint) { - // out.format("## Group: %s%n%n", getJsonSegment(typeDeclaration)); - // out.println(getJavaDoc(typeDeclaration)); - // out.println("\n"); - - var direction = ""; - if (endpoint instanceof Metamodel.ServerRequest sr) - direction = "client -> server"; - else if (endpoint instanceof Metamodel.ClientRequest sr) - direction = "server -> client"; - else if (endpoint instanceof Metamodel.ServerNotification sr) - direction = "client ~~> server"; - else if (endpoint instanceof Metamodel.ClientNotification sr) - direction = "server ~~> client"; - - out.format("### %s (`%s`) %n%n", endpoint.name(), direction); - out.format("```%n"); - var args = endpoint.args(); - final var a = args.stream() - .map(it -> "%s : %s".formatted(it.name(), it.type())) - .collect(Collectors.joining(", ")); - if (endpoint instanceof Metamodel.ServerRequest sr) { - out.format("Server.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); - } else if (endpoint instanceof Metamodel.ClientRequest sr) - out.format("Client.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); - else if (endpoint instanceof Metamodel.ServerNotification sr) - out.format("Server.%s( %s ) **async**%n", endpoint.name(), a); - else if (endpoint instanceof Metamodel.ClientNotification sr) - out.format("Client.%s( %s ) **async**%n", endpoint.name(), a); - out.format("```%n"); - - out.println(endpoint.documentation()); - out.println(); - } - - private void printType(Metamodel.Type type) { - out.format("### Type: %s%n", type.name()); - if (type instanceof Metamodel.ObjectType ot) { - out.format(""" - ``` - type %s { - %s - } - ``` - """.formatted(type.name(), - ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) - .map(it -> "\t%s : %s".formatted(it.name(), it.type())) - .collect(Collectors.joining("\n")))); - } - - if (type instanceof Metamodel.EnumType et) { - out.format(""" - ``` - enum %s { %s } - ``` - """.formatted(type.name(), String.join(", ", et.values()))); - out.format(type.documentation()); - } - out.format(type.documentation()); - out.println(); - } - - /* - * private static String getCallName (MethodDeclaration m, TypeDeclaration < ?>td){ - * var annotationExpr = m.getAnnotationByName("JsonNotification").or( - * () -> m.getAnnotationByName("JsonRequest")) - * .orElseThrow(); - * - * var segment = getJsonSegment(td) + "/"; - * String name = ""; - * - * if (annotationExpr.isMarkerAnnotationExpr()) { - * name = m.getNameAsString(); - * } else if (annotationExpr.isSingleMemberAnnotationExpr()) { - * var sma = annotationExpr.asSingleMemberAnnotationExpr(); - * name = sma.getMemberValue().asLiteralStringValueExpr().getValue(); - * } else { - * var ne = annotationExpr.asNormalAnnotationExpr(); - * for (MemberValuePair pair : ne.getPairs()) { - * switch (pair.getName().asString()) { - * case "value": - * name = pair.getValue().asLiteralStringValueExpr().getValue(); - * break; - * case "useSegment": - * if (!pair.getValue().asBooleanLiteralExpr().getValue()) { - * segment = ""; - * } - * } - * } - * } - * return segment + name; - * } - * - * @Nonnull - * private static String getJavaDoc (NodeWithJavadoc < ? > typeDeclaration){ - * if (typeDeclaration.getJavadoc().isPresent()) { - * final var javadoc = typeDeclaration.getJavadoc().get(); - * return javadoc.getDescription().toText() - * + "\n\n" - * + javadoc.getBlockTags().stream().map(it -> "* " + it.toText()) - * .collect(Collectors.joining("\n")); - * } - * return ""; - * } - * - * private static String type (MethodDeclaration method){ - * if (method.getAnnotationByName("JsonNotification").isPresent()) - * return "notification"; - * if (method.getAnnotationByName("JsonRequest").isPresent()) - * return "request"; - * return ""; - * } - * - * private static boolean isExported (MethodDeclaration method){ - * return method.getAnnotationByName("JsonNotification").isPresent() - * || method.getAnnotationByName("JsonRequest").isPresent(); - * } - * - * private void printHeader () { - * out.format("# KeY-API%n%n"); - * } - * - * private void printFooter () { - * } - * - * - * /* - * private static boolean hasJsonSegment(TypeDeclaration it) { - * return it.getAnnotationByName("JsonSegment").isPresent(); - * } - * - * private static String getJsonSegment(TypeDeclaration it) { - * var ae = it.getAnnotationByName("JsonSegment").get(); - * return ae.asSingleMemberAnnotationExpr().getMemberValue() - * .asLiteralStringValueExpr().getValue(); - * } - */ - -} diff --git a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java new file mode 100644 index 00000000000..1521d2351ce --- /dev/null +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java @@ -0,0 +1,107 @@ +package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author Alexander Weigl + * @version 1 (29.10.23) + */ +public class DocGen implements Supplier { + private final Metamodel.KeyApi metamodel; + private PrintWriter out; + + public DocGen(Metamodel.KeyApi metamodel) { + this.metamodel = metamodel; + } + + @Override + public String get() { + final StringWriter target = new StringWriter(); + try (var out = new PrintWriter(target)) { + this.out = out; + printHeader(); + + out.format("## Types%n"); + metamodel.types() + .stream().sorted(Comparator.comparing(Metamodel.Type::name)) + .forEach(this::printType); + + out.format("## Endpoints%n"); + metamodel.endpoints() + .stream().sorted(Comparator.comparing(Metamodel.Endpoint::name)) + .forEach(this::endpoints); + printFooter(); + } + return target.toString(); + } + + private void printFooter() { + + } + + private void printHeader() { + + + } + + private void endpoints(Metamodel.Endpoint endpoint) { + var direction = switch (endpoint) { + case Metamodel.ServerRequest sr -> "client -> server"; + case Metamodel.ClientRequest sr -> "server -> client"; + case Metamodel.ServerNotification sr -> "client ~~> server"; + case Metamodel.ClientNotification sr -> "server ~~> client"; + }; + + out.format("### %s (`%s`) %n%n", endpoint.name(), direction); + out.format("```%n"); + var args = endpoint.args(); + final var a = args.stream() + .map(it -> "%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining(", ")); + switch (endpoint) { + case Metamodel.ServerRequest sr -> out.format("Server.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); + case Metamodel.ClientRequest sr -> out.format("Client.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); + case Metamodel.ServerNotification _ -> out.format("Server.%s( %s ) **async**%n", endpoint.name(), a); + case Metamodel.ClientNotification _ -> out.format("Client.%s( %s ) **async**%n", endpoint.name(), a); + default -> { + } + } + out.format("```%n"); + + out.println(endpoint.documentation()); + out.println(); + } + + private void printType(Metamodel.Type type) { + out.format("### Type: %s%n", type.name()); + if (type instanceof Metamodel.ObjectType ot) { + out.format(""" + ``` + type %s { + %s + } + ``` + """.formatted(type.name(), + ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) + .map(it -> "\t%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining("\n")))); + } + + if (type instanceof Metamodel.EnumType et) { + out.format(""" + ``` + enum %s { %s } + ``` + """.formatted(type.name(), String.join(", ", et.values()))); + out.format(type.documentation()); + } + out.format(type.documentation()); + out.println(); + } +} diff --git a/keyext.api.doc/src/main/java/ExtractMetaData.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java similarity index 61% rename from keyext.api.doc/src/main/java/ExtractMetaData.java rename to keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java index d053b9268d3..e605b1ceb39 100644 --- a/keyext.api.doc/src/main/java/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java @@ -1,46 +1,83 @@ -/* This file is part of KeY - https://key-project.org +package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.reflect.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Supplier; -import de.uka.ilkd.key.proof.Proof; - -import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseProblemException; import com.github.javaparser.ParserConfiguration; -import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; -import com.google.gson.*; +import com.github.javaparser.javadoc.Javadoc; +import com.github.javaparser.javadoc.description.JavadocDescription; +import com.github.javaparser.utils.SourceRoot; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializer; +import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.jsonrpc.services.JsonSegment; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.keyproject.key.api.remoteapi.KeyApi; import org.keyproject.key.api.remoteclient.ClientApi; -import sun.misc.Unsafe; +import picocli.CommandLine; +import picocli.CommandLine.Option; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; /** * @author Alexander Weigl * @version 1 (14.10.23) */ -public class ExtractMetaData { - private static PrintWriter out; +@NullMarked +@CommandLine.Command(name = "gendoc", + mixinStandardHelpOptions = true, + version = "gendoc 1.0", + description = "Generates the documentation for key.api") +public class ExtractMetaData implements Callable { + private final List endpoints = new LinkedList<>(); + private final List types = new LinkedList<>(); + private final Metamodel.KeyApi keyApi = new Metamodel.KeyApi(endpoints, types); + private SourceRoot sourceRoot = new SourceRoot(Paths.get(".")); + - private static final List endpoints = new LinkedList<>(); - private static final List types = new LinkedList<>(); - private static final Metamodel.KeyApi keyApi = new Metamodel.KeyApi(endpoints, types); + @Option(names = {"-s", "--source"}, description = "Source folder for getting JavaDoc") + private @Nullable Path source = Paths.get("keyext.api", "src", "main", "java"); + + @Option(names = {"-o", "--output"}, description = "Output folder") + private Path output = Paths.get("out"); public static void main(String[] args) { + int exitCode = new CommandLine(new ExtractMetaData()).execute(args); + System.exit(exitCode); + } + + @Override + public Integer call() throws IOException { + if (source != null) { + ParserConfiguration config = new ParserConfiguration(); + config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_21); + config.setAttributeComments(true); + config.setLexicalPreservationEnabled(false); + config.setStoreTokens(false); + config.setIgnoreAnnotationsWhenAttributingComments(true); + config.setDoNotAssignCommentsPrecedingEmptyLines(true); + sourceRoot = new SourceRoot(source, config); + } + for (Method method : KeyApi.class.getMethods()) { addServerEndpoint(method); } @@ -49,17 +86,20 @@ public static void main(String[] args) { addClientEndpoint(method); } + Files.createDirectories(output); + runGenerator("api.meta.json", (a) -> () -> getGson().toJson(a)); runGenerator("api.meta.md", DocGen::new); - runGenerator("keydata.py", PythionGenerator.PyDataGen::new); - runGenerator("server.py", PythionGenerator.PyApiGen::new); + runGenerator("keydata.py", PythonGenerator.PyDataGen::new); + runGenerator("server.py", PythonGenerator.PyApiGen::new); + + return 0; } - private static void runGenerator(String target, - Function> api) { + private void runGenerator(String target, Function> api) { try { var n = api.apply(keyApi); - Files.writeString(Paths.get(target), n.get()); + Files.writeString(output.resolve(target), n.get()); } catch (IOException e) { e.printStackTrace(); } @@ -68,22 +108,17 @@ private static void runGenerator(String target, private static Gson getGson() { return new GsonBuilder() .setPrettyPrinting() - .registerTypeAdapter(Type.class, new JsonSerializer() { - @Override - public JsonElement serialize(Metamodel.Type src, Type typeOfSrc, - JsonSerializationContext context) { - JsonObject json = (JsonObject) context.serialize(src); - json.addProperty("kind", src.kind()); - return json; - } + .registerTypeAdapter(Type.class, (JsonSerializer) (src, typeOfSrc, context) -> { + JsonObject json = (JsonObject) context.serialize(src); + json.addProperty("kind", src.kind()); + return json; }) .create(); } - private static void addServerEndpoint(Method method) { + private void addServerEndpoint(Method method) { var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); - if (jsonSegment == null) - return; + if (jsonSegment == null) return; var segment = jsonSegment.value(); var req = method.getAnnotation(JsonRequest.class); @@ -118,28 +153,32 @@ private static void addServerEndpoint(Method method) { throw new IllegalStateException(); } - private static String findDocumentation(Method method) { - // TODO get compilation, get type, find method, getJavaDocComment() - return ""; + private String findDocumentation(Method method) { + return findCompilationUnit(method.getDeclaringClass()) + .map(it -> it.getMethodsByName(method.getName())) + .map(List::getFirst) + .flatMap(NodeWithJavadoc::getJavadoc) + .map(Javadoc::getDescription) + .map(JavadocDescription::toText) + .orElse(""); } - private static List translate(Parameter[] parameters) { - return Arrays.stream(parameters).map(ExtractMetaData::translate).toList(); + private List translate(Parameter[] parameters) { + return Arrays.stream(parameters).map(this::translate).toList(); } - private static Metamodel.Argument translate(Parameter parameter) { + private Metamodel.Argument translate(Parameter parameter) { var type = getOrFindType(parameter.getType()).name(); return new Metamodel.Argument(parameter.getName(), type); } - private static Metamodel.Type getOrFindType(Class type) { + private Metamodel.Type getOrFindType(Class type) { System.out.println(type); if (type == CompletableFuture.class) { return getOrFindType(type.getTypeParameters()[0].getClass()); } - if (type == Unsafe.class || type == Class.class || type == Constructor.class - || type == Proof.class) { + if (type == Class.class || type == Constructor.class || type == Proof.class) { throw new IllegalStateException("Forbidden class reached!"); } @@ -178,12 +217,12 @@ private static Metamodel.Type getOrFindType(Class type) { return a; } - private static Metamodel.Type createType(Class type) { + private Metamodel.Type createType(Class type) { final var documentation = findDocumentation(type); if (type.isEnum()) return new Metamodel.EnumType(type.getSimpleName(), - Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), - documentation); + Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), + documentation); var obj = new Metamodel.ObjectType(type.getSimpleName(), new ArrayList<>(), documentation); @@ -194,34 +233,23 @@ private static Metamodel.Type createType(Class type) { return obj; } - private static String findDocumentation(Class type) { - var parser = initJavaParser(); - var fileName = findFileForType(type); - - if (Files.exists(fileName)) { - try { - return parser.parse(fileName).getResult().flatMap(CompilationUnit::getPrimaryType) - .flatMap(NodeWithJavadoc::getJavadocComment) - .map(Comment::getContent).orElse(""); - } catch (IOException e) { - e.printStackTrace(); - return ""; - } - } else - return ""; + private String findDocumentation(Class type) { + return findCompilationUnit(type) + .flatMap(NodeWithJavadoc::getJavadocComment) + .map(Comment::getContent) + .orElse(""); } - private static Path findFileForType(Class type) { - final var folderString = type.getPackageName().replaceAll("\\.", "/"); - var folder = Paths.get("keyext.api", "src", "main", "java", folderString); - final Class declaringClass = type.getDeclaringClass(); - var fileName = (declaringClass != null ? declaringClass : type).getSimpleName() + ".java"; - var file = folder.resolve(fileName); - return file; + private Optional> findCompilationUnit(Class type) { + try { + return sourceRoot.parse(type.getPackageName(), type.getSimpleName() + ".java").getPrimaryType(); + } catch (ParseProblemException e) { + return Optional.empty(); + } } - private static void addClientEndpoint(Method method) { + private void addClientEndpoint(Method method) { var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); var segment = jsonSegment.value(); @@ -248,8 +276,8 @@ private static void addClientEndpoint(Method method) { } } - private static String callMethodName(String method, String segment, String userValue, - boolean useSegment) { + private static String callMethodName(String method, String segment, @Nullable String userValue, + boolean useSegment) { if (!useSegment) { if (userValue == null || userValue.isBlank()) { return method; @@ -265,12 +293,12 @@ private static String callMethodName(String method, String segment, String userV } } - private static Metamodel.Type getOrFindType(Type genericReturnType) { - if (genericReturnType instanceof Class c) + private Metamodel.@Nullable Type getOrFindType(Type genericReturnType) { + if (genericReturnType instanceof Class c) return getOrFindType(c); if (genericReturnType instanceof ParameterizedType pt) { if (Objects.equals(pt.getRawType().getTypeName(), - CompletableFuture.class.getTypeName())) { + CompletableFuture.class.getTypeName())) { return getOrFindType(pt.getActualTypeArguments()[0]); } if (Objects.equals(pt.getRawType().getTypeName(), List.class.getTypeName())) { @@ -286,16 +314,4 @@ private static Metamodel.Type getOrFindType(Type genericReturnType) { } return null; } - - static JavaParser initJavaParser() { - ParserConfiguration config = new ParserConfiguration(); - config.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17_PREVIEW); - config.setAttributeComments(true); - config.setLexicalPreservationEnabled(false); - config.setStoreTokens(false); - config.setIgnoreAnnotationsWhenAttributingComments(true); - config.setDoNotAssignCommentsPrecedingEmptyLines(true); - return new JavaParser(config); - } - } diff --git a/keyext.api.doc/src/main/java/Metamodel.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java similarity index 96% rename from keyext.api.doc/src/main/java/Metamodel.java rename to keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java index 62146f0f5ee..e9b5780c95a 100644 --- a/keyext.api.doc/src/main/java/Metamodel.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java @@ -1,4 +1,4 @@ -/* This file is part of KeY - https://key-project.org +package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ import java.util.List; diff --git a/keyext.api.doc/src/main/java/PythionGenerator.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java similarity index 93% rename from keyext.api.doc/src/main/java/PythionGenerator.java rename to keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java index 9fc222a1221..395991dba8f 100644 --- a/keyext.api.doc/src/main/java/PythionGenerator.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java @@ -1,4 +1,4 @@ -/* This file is part of KeY - https://key-project.org +package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ import java.io.PrintWriter; @@ -12,12 +12,12 @@ * @author Alexander Weigl * @version 1 (29.10.23) */ -public abstract class PythionGenerator implements Supplier { +public abstract class PythonGenerator implements Supplier { protected final Metamodel.KeyApi metamodel; protected PrintWriter out; protected final StringWriter target = new StringWriter(); - public PythionGenerator(Metamodel.KeyApi metamodel) { + public PythonGenerator(Metamodel.KeyApi metamodel) { this.metamodel = metamodel; } @@ -34,8 +34,7 @@ public String get() { protected String asPython(String typeName) { return switch (typeName) { - case "INT" -> "int"; - case "LONG" -> "int"; + case "INT", "LONG" -> "int"; case "STRING" -> "str"; case "BOOL" -> "bool"; case "DOUBLE" -> "float"; @@ -57,9 +56,8 @@ protected String asPython(Metamodel.Type t) { if (t instanceof Metamodel.BuiltinType bt) { return switch (bt) { - case INT -> "int"; - case LONG -> "int"; - case STRING -> "str"; + case INT, LONG -> "int"; + case STRING -> "str"; case BOOL -> "bool"; case DOUBLE -> "float"; }; @@ -73,7 +71,7 @@ protected Metamodel.Type findType(String typeName) { } - public static class PyApiGen extends PythionGenerator { + public static class PyApiGen extends PythonGenerator { public PyApiGen(Metamodel.KeyApi metamodel) { super(metamodel); } @@ -123,7 +121,7 @@ private void clientEndpoint(Metamodel.Endpoint endpoint) { out.format(" def %s(self, %s):%n", endpoint.name().replace("/", "_"), args); } out.format(" \"\"\"%s\"\"\"%n%n", endpoint.documentation()); - out.format(" pass".formatted(endpoint.name(), "")); + out.format(" pass"); out.println(); out.println(); } @@ -134,7 +132,7 @@ class KeyServer(ServerBase):%n def __init__(self, endpoint : LspEndpoint): super().__init__(endpoint) - """); + """); sorted.forEach(this::serverEndpoint); } @@ -169,7 +167,7 @@ private void serverEndpoint(Metamodel.Endpoint endpoint) { } - public static class PyDataGen extends PythionGenerator { + public static class PyDataGen extends PythonGenerator { public PyDataGen(Metamodel.KeyApi metamodel) { super(metamodel); } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java index 1e3a0539711..44cb61cf8b5 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/KeyApiImpl.java @@ -389,8 +389,6 @@ public CompletableFuture loadExample(String id) { var proofId = new ProofId(envId, proof.name().toString()); return data.register(proofId, proof); } catch (ProblemLoaderException e) { - if (proof != null) - proof.dispose(); if (env != null) env.dispose(); throw new RuntimeException(e); @@ -442,8 +440,6 @@ public CompletableFuture loadKey(String content) { var proofId = new ProofId(envId, proof.name().toString()); return data.register(proofId, proof); } catch (ProblemLoaderException | IOException e) { - if (proof != null) - proof.dispose(); if (env != null) env.dispose(); throw new RuntimeException(e); @@ -459,8 +455,8 @@ public CompletableFuture loadTerm(String term) { @Override public CompletableFuture> load(LoadParams params) { return CompletableFutures.computeAsync((c) -> { - Proof proof = null; - KeYEnvironment env = null; + Proof proof; + KeYEnvironment env; try { var loader = control.load(JavaProfile.getDefaultProfile(), params.keyFile(), @@ -482,10 +478,6 @@ public CompletableFuture> load(LoadParams params) return Either.forLeft(envId); } } catch (ProblemLoaderException e) { - if (proof != null) - proof.dispose(); - if (env != null) - env.dispose(); throw new RuntimeException(e); } }); @@ -579,6 +571,4 @@ public void showIssueDialog(Collection issues) { super.showIssueDialog(issues); } } - - } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java index d9c619f4dea..1b4184e58dd 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/TermActionDesc.java @@ -6,9 +6,30 @@ import org.keyproject.key.api.data.KeyIdentifications.TermActionId; /** + * This class represents an action that can be executed on a term. + * * @author Alexander Weigl * @version 1 (13.10.23) */ -public record TermActionDesc(TermActionId commandId, String displayName, String description, String category, - TermActionKind kind) { +public record TermActionDesc( + /** + * Unique identification + */ + TermActionId commandId, + /** + * A string to display to the user. + */ + String displayName, + /** + * Long description of the action for the user. + */ + String description, + /** + * A string identifying a category + */ + String category, + /** + * Kind of the action + */ + TermActionKind kind) { } diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java new file mode 100644 index 00000000000..6b8d1608b79 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Alexander Weigl + * @version 1 (20.10.24) + */ +@NullMarked package org.keyproject.key.api.data; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/package-info.java new file mode 100644 index 00000000000..56416d92034 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Alexander Weigl + * @version 1 (20.10.24) + */ +@NullMarked package org.keyproject.key.api; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java new file mode 100644 index 00000000000..f0362f688b0 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Alexander Weigl + * @version 1 (20.10.24) + */ +@NullMarked package org.keyproject.key.api.remoteapi; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java new file mode 100644 index 00000000000..cf1561a11d7 --- /dev/null +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Alexander Weigl + * @version 1 (20.10.24) + */ +@NullMarked package org.keyproject.key.api.remoteclient; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file From 8ece37547d9710bf5698d7ca1a7581a4edec0e2d Mon Sep 17 00:00:00 2001 From: Alexander Weigl Date: Fri, 22 Nov 2024 22:38:21 +0100 Subject: [PATCH 22/50] start of a simple Java client --- .../uka/ilkd/key/rule/IntSemanticsTest.java | 18 ++- .../org/key_project/key/api/doc/DocGen.java | 18 ++- .../key/api/doc/ExtractMetaData.java | 70 +++++----- .../key_project/key/api/doc/Metamodel.java | 9 +- .../key/api/doc/PythonGenerator.java | 11 +- .../keyproject/key/api/data/package-info.java | 5 +- .../org/keyproject/key/api/package-info.java | 5 +- .../key/api/remoteapi/package-info.java | 5 +- .../key/api/remoteclient/package-info.java | 5 +- keyext.caching/build.gradle | 2 +- keyext.client.java/build.gradle | 35 +++++ .../keyextclientjava/HelloApplication.java | 22 ++++ .../formal/keyextclientjava/KeyRemote.java | 10 ++ .../formal/keyextclientjava/MyKeyClient.java | 54 ++++++++ .../iti/formal/keyextclientjava/RPCLayer.java | 120 ++++++++++++++++++ .../formal/keyextclientjava/TreeNodeId.java | 8 ++ .../formal/keyextclientjava/hello-view.fxml | 16 +++ settings.gradle | 6 +- 18 files changed, 360 insertions(+), 59 deletions(-) create mode 100644 keyext.client.java/build.gradle create mode 100644 keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/HelloApplication.java create mode 100644 keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/KeyRemote.java create mode 100644 keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/MyKeyClient.java create mode 100644 keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/RPCLayer.java create mode 100644 keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/TreeNodeId.java create mode 100644 keyext.client.java/src/main/resources/edu/kit/iti/formal/keyextclientjava/hello-view.fxml diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java b/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java index 70f8b8fffa8..9a61ae41912 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java @@ -5,9 +5,7 @@ import java.io.File; -import de.uka.ilkd.key.api.KeYApi; -import de.uka.ilkd.key.api.ProofApi; -import de.uka.ilkd.key.api.ProofManagementApi; +import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.io.ProblemLoaderException; @@ -41,8 +39,8 @@ class IntSemanticsTest { "checkedOF/mOFCheck.proof" }) void testSemanticsProvable(String filename) throws ProblemLoaderException { File proofFile = new File(TEST_DIR, filename); - ProofManagementApi pmapi = KeYApi.loadProof(proofFile); - Proof proof = pmapi.getLoadedProof().getProof(); + var env = KeYEnvironment.load(proofFile); + Proof proof = env.getLoadedProof(); // Proof should be reloaded completely now. If not, the int semantics are probably broken. Assertions.assertTrue(proof.closed()); } @@ -58,12 +56,12 @@ void testSemanticsProvable(String filename) throws ProblemLoaderException { @ValueSource(strings = { "java/mJavaWrong.key", "uncheckedOF/mBigintWrong.key", "checkedOF/mOFCheckWrong.key", }) - void testSemanticsUnprovable(String filename) throws ProblemLoaderException { + void testSemanticsUnprovable(String filename) + throws ProblemLoaderException, InterruptedException { File keyFile = new File(TEST_DIR, filename); - ProofManagementApi pmapi = KeYApi.loadFromKeyFile(keyFile); - ProofApi proofApi = pmapi.getLoadedProof(); - Proof proof = proofApi.getProof(); - proofApi.getEnv().getProofControl().startAndWaitForAutoMode(proof); + final var env = KeYEnvironment.load(keyFile); + var proof = env.getLoadedProof(); + env.getProofControl().startAndWaitForAutoMode(proof); // we expect that exactly one branch (the overflow check) is open now: Assertions.assertEquals(1, proof.openGoals().size()); } diff --git a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java index 1521d2351ce..c71335d2cf6 100644 --- a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/DocGen.java @@ -1,6 +1,12 @@ -package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org +/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.key.api.doc;/* + * This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version + * 2 + * SPDX-License-Identifier: GPL-2.0-only + */ import java.io.PrintWriter; import java.io.StringWriter; @@ -67,8 +73,8 @@ private void endpoints(Metamodel.Endpoint endpoint) { switch (endpoint) { case Metamodel.ServerRequest sr -> out.format("Server.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); case Metamodel.ClientRequest sr -> out.format("Client.%s( %s ) -> %s%n", endpoint.name(), a, sr.returnType().name()); - case Metamodel.ServerNotification _ -> out.format("Server.%s( %s ) **async**%n", endpoint.name(), a); - case Metamodel.ClientNotification _ -> out.format("Client.%s( %s ) **async**%n", endpoint.name(), a); + case Metamodel.ServerNotification ignored -> out.format("Server.%s( %s ) **async**%n", endpoint.name(), a); + case Metamodel.ClientNotification ignored -> out.format("Client.%s( %s ) **async**%n", endpoint.name(), a); default -> { } } @@ -88,9 +94,9 @@ private void printType(Metamodel.Type type) { } ``` """.formatted(type.name(), - ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) - .map(it -> "\t%s : %s".formatted(it.name(), it.type())) - .collect(Collectors.joining("\n")))); + ot.fields().stream().sorted(Comparator.comparing(Metamodel.Field::name)) + .map(it -> "\t%s : %s".formatted(it.name(), it.type())) + .collect(Collectors.joining("\n")))); } if (type instanceof Metamodel.EnumType et) { diff --git a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java index e605b1ceb39..86a9bb7e945 100644 --- a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/ExtractMetaData.java @@ -1,6 +1,26 @@ -package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org +/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.key.api.doc;/* + * This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version + * 2 + * SPDX-License-Identifier: GPL-2.0-only + */ + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; + +import de.uka.ilkd.key.proof.Proof; import com.github.javaparser.ParseProblemException; import com.github.javaparser.ParserConfiguration; @@ -14,7 +34,6 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonSerializer; -import de.uka.ilkd.key.proof.Proof; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; @@ -26,27 +45,15 @@ import picocli.CommandLine; import picocli.CommandLine.Option; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Supplier; - /** * @author Alexander Weigl * @version 1 (14.10.23) */ @NullMarked @CommandLine.Command(name = "gendoc", - mixinStandardHelpOptions = true, - version = "gendoc 1.0", - description = "Generates the documentation for key.api") + mixinStandardHelpOptions = true, + version = "gendoc 1.0", + description = "Generates the documentation for key.api") public class ExtractMetaData implements Callable { private final List endpoints = new LinkedList<>(); private final List types = new LinkedList<>(); @@ -54,10 +61,10 @@ public class ExtractMetaData implements Callable { private SourceRoot sourceRoot = new SourceRoot(Paths.get(".")); - @Option(names = {"-s", "--source"}, description = "Source folder for getting JavaDoc") + @Option(names = { "-s", "--source" }, description = "Source folder for getting JavaDoc") private @Nullable Path source = Paths.get("keyext.api", "src", "main", "java"); - @Option(names = {"-o", "--output"}, description = "Output folder") + @Option(names = { "-o", "--output" }, description = "Output folder") private Path output = Paths.get("out"); public static void main(String[] args) { @@ -108,17 +115,19 @@ private void runGenerator(String target, Function) (src, typeOfSrc, context) -> { - JsonObject json = (JsonObject) context.serialize(src); - json.addProperty("kind", src.kind()); - return json; - }) + .registerTypeAdapter(Type.class, + (JsonSerializer) (src, typeOfSrc, context) -> { + JsonObject json = (JsonObject) context.serialize(src); + json.addProperty("kind", src.kind()); + return json; + }) .create(); } private void addServerEndpoint(Method method) { var jsonSegment = method.getDeclaringClass().getAnnotation(JsonSegment.class); - if (jsonSegment == null) return; + if (jsonSegment == null) + return; var segment = jsonSegment.value(); var req = method.getAnnotation(JsonRequest.class); @@ -221,8 +230,8 @@ private Metamodel.Type createType(Class type) { final var documentation = findDocumentation(type); if (type.isEnum()) return new Metamodel.EnumType(type.getSimpleName(), - Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), - documentation); + Arrays.stream(type.getEnumConstants()).map(Object::toString).toList(), + documentation); var obj = new Metamodel.ObjectType(type.getSimpleName(), new ArrayList<>(), documentation); @@ -242,7 +251,8 @@ private String findDocumentation(Class type) { private Optional> findCompilationUnit(Class type) { try { - return sourceRoot.parse(type.getPackageName(), type.getSimpleName() + ".java").getPrimaryType(); + return sourceRoot.parse(type.getPackageName(), type.getSimpleName() + ".java") + .getPrimaryType(); } catch (ParseProblemException e) { return Optional.empty(); } @@ -277,7 +287,7 @@ private void addClientEndpoint(Method method) { } private static String callMethodName(String method, String segment, @Nullable String userValue, - boolean useSegment) { + boolean useSegment) { if (!useSegment) { if (userValue == null || userValue.isBlank()) { return method; @@ -298,7 +308,7 @@ private static String callMethodName(String method, String segment, @Nullable St return getOrFindType(c); if (genericReturnType instanceof ParameterizedType pt) { if (Objects.equals(pt.getRawType().getTypeName(), - CompletableFuture.class.getTypeName())) { + CompletableFuture.class.getTypeName())) { return getOrFindType(pt.getActualTypeArguments()[0]); } if (Objects.equals(pt.getRawType().getTypeName(), List.class.getTypeName())) { diff --git a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java index e9b5780c95a..d71d2c62b30 100644 --- a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/Metamodel.java @@ -1,6 +1,13 @@ -package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org +/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.key.api.doc;/* + * This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version + * 2 + * SPDX-License-Identifier: GPL-2.0-only + */ + import java.util.List; import org.jspecify.annotations.NullMarked; diff --git a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java index 395991dba8f..616372e5af5 100644 --- a/keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java +++ b/keyext.api.doc/src/main/java/org/key_project/key/api/doc/PythonGenerator.java @@ -1,6 +1,13 @@ -package org.key_project.key.api.doc;/* This file is part of KeY - https://key-project.org +/* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.key.api.doc;/* + * This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version + * 2 + * SPDX-License-Identifier: GPL-2.0-only + */ + import java.io.PrintWriter; import java.io.StringWriter; import java.util.Comparator; @@ -57,7 +64,7 @@ protected String asPython(Metamodel.Type t) { if (t instanceof Metamodel.BuiltinType bt) { return switch (bt) { case INT, LONG -> "int"; - case STRING -> "str"; + case STRING -> "str"; case BOOL -> "bool"; case DOUBLE -> "float"; }; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java index 6b8d1608b79..39ecb9745a4 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/data/package-info.java @@ -2,6 +2,7 @@ * @author Alexander Weigl * @version 1 (20.10.24) */ -@NullMarked package org.keyproject.key.api.data; +@NullMarked +package org.keyproject.key.api.data; -import org.jspecify.annotations.NullMarked; \ No newline at end of file +import org.jspecify.annotations.NullMarked; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/package-info.java index 56416d92034..c979030e065 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/package-info.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/package-info.java @@ -2,6 +2,7 @@ * @author Alexander Weigl * @version 1 (20.10.24) */ -@NullMarked package org.keyproject.key.api; +@NullMarked +package org.keyproject.key.api; -import org.jspecify.annotations.NullMarked; \ No newline at end of file +import org.jspecify.annotations.NullMarked; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java index f0362f688b0..ccaca3e03b6 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteapi/package-info.java @@ -2,6 +2,7 @@ * @author Alexander Weigl * @version 1 (20.10.24) */ -@NullMarked package org.keyproject.key.api.remoteapi; +@NullMarked +package org.keyproject.key.api.remoteapi; -import org.jspecify.annotations.NullMarked; \ No newline at end of file +import org.jspecify.annotations.NullMarked; diff --git a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java index cf1561a11d7..2151dd10601 100644 --- a/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java +++ b/keyext.api/src/main/java/org/keyproject/key/api/remoteclient/package-info.java @@ -2,6 +2,7 @@ * @author Alexander Weigl * @version 1 (20.10.24) */ -@NullMarked package org.keyproject.key.api.remoteclient; +@NullMarked +package org.keyproject.key.api.remoteclient; -import org.jspecify.annotations.NullMarked; \ No newline at end of file +import org.jspecify.annotations.NullMarked; diff --git a/keyext.caching/build.gradle b/keyext.caching/build.gradle index 45cf447440d..5f1e06b2828 100644 --- a/keyext.caching/build.gradle +++ b/keyext.caching/build.gradle @@ -3,6 +3,6 @@ description "Caching of provable nodes to make proving with KeY faster." dependencies { implementation project(":key.core") implementation project(":key.ui") - implementation project(":keyext.slicing") + implementation "com.google.code.gson:gson:2.11.0" } \ No newline at end of file diff --git a/keyext.client.java/build.gradle b/keyext.client.java/build.gradle new file mode 100644 index 00000000000..430cc898bd2 --- /dev/null +++ b/keyext.client.java/build.gradle @@ -0,0 +1,35 @@ +plugins { + id 'java' + id 'application' + id 'org.javamodularity.moduleplugin' version '1.8.12' + id 'org.openjfx.javafxplugin' version '0.0.13' +} + +repositories { + mavenCentral() +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +application { + mainClass = 'edu.kit.iti.formal.keyextclientjava.HelloApplication' +} + +javafx { + version = '21.0.5' + modules = ['javafx.controls', 'javafx.fxml'] +} + +dependencies { + implementation('org.controlsfx:controlsfx:11.2.1') + implementation('org.kordamp.ikonli:ikonli-javafx:12.3.1') + implementation('org.kordamp.ikonli:ikonli-fontawesome5-pack:12.3.1') + implementation('org.kordamp.bootstrapfx:bootstrapfx-core:0.4.0') + implementation('com.google.code.gson:gson:2.11.0') +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/HelloApplication.java b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/HelloApplication.java new file mode 100644 index 00000000000..b2b739c9baa --- /dev/null +++ b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/HelloApplication.java @@ -0,0 +1,22 @@ +package edu.kit.iti.formal.keyextclientjava; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.stage.Stage; + +import java.io.IOException; + +public class HelloApplication extends Application { + @Override + public void start(Stage stage) throws IOException { + Scene scene = new Scene(new MyKeyClient().root, 320, 240); + stage.setTitle("KeY Demo"); + stage.setScene(scene); + stage.show(); + } + + public static void main(String[] args) { + launch(); + } +} \ No newline at end of file diff --git a/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/KeyRemote.java b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/KeyRemote.java new file mode 100644 index 00000000000..fa6cb27c097 --- /dev/null +++ b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/KeyRemote.java @@ -0,0 +1,10 @@ +package edu.kit.iti.formal.keyextclientjava; + +/** + * @author Alexander Weigl + * @version 1 (22.11.24) + */ +public class KeyRemote { + public KeyRemote(RPCLayer rpcLayer) { + } +} diff --git a/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/MyKeyClient.java b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/MyKeyClient.java new file mode 100644 index 00000000000..12fd1aa6bed --- /dev/null +++ b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/MyKeyClient.java @@ -0,0 +1,54 @@ +package edu.kit.iti.formal.keyextclientjava; + +import javafx.geometry.Orientation; +import javafx.scene.control.*; +import javafx.scene.layout.BorderPane; +import javafx.stage.FileChooser; +import org.controlsfx.glyphfont.FontAwesome; +import org.kordamp.ikonli.Ikon; +import org.kordamp.ikonli.fontawesome5.FontAwesomeRegular; +import org.kordamp.ikonli.javafx.FontIcon; + +import javax.swing.*; +import java.io.IOException; +import java.util.concurrent.ForkJoinPool; + +/** + * @author Alexander Weigl + * @version 1 (22.11.24) + */ +public class MyKeyClient { + private static final String JAR_FILE = ""; + private final ToolBar toolbar = new ToolBar(); + private final Label txtStatus = new Label("Yeah!"); + public final BorderPane root = new BorderPane(); + private final TreeView tnid = new TreeView<>(); + private final TextArea txtSequentView = new TextArea(); + + private final FileChooser fc = new FileChooser(); + + public MyKeyClient() { + //region toolbar + var btnOpen = new Button("Open", new FontIcon(FontAwesomeRegular.FOLDER_OPEN)); + btnOpen.setOnAction(actionEvent -> openFile()); + toolbar.getItems().setAll(btnOpen, new Separator(Orientation.VERTICAL)); + //endregion + + var splitCenter = new SplitPane(tnid, txtSequentView); + splitCenter.setDividerPositions(.2); + root.setTop(toolbar); + root.setCenter(splitCenter); + root.setBottom(txtStatus); + + var startKey = ForkJoinPool.commonPool().submit(this::startKey); + } + + private Object startKey() throws IOException { + return new KeyRemote(RPCLayer.startWithCLI(JAR_FILE)); + + } + + private void openFile() { + fc.showOpenDialog(null); + } +} diff --git a/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/RPCLayer.java b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/RPCLayer.java new file mode 100644 index 00000000000..70eabaefe79 --- /dev/null +++ b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/RPCLayer.java @@ -0,0 +1,120 @@ +package edu.kit.iti.formal.keyextclientjava; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.*; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; + +/** + * @author Alexander Weigl + * @version 1 (22.11.24) + */ +public final class RPCLayer { + private final GsonBuilder builder = new GsonBuilder(); + // unclear whether concurrent use is possible + private final Gson gson = builder.create(); + + private final BufferedReader incoming; + private final Writer outgoing; + private final Thread threadListener; + + private ReentrantLock lockSend = new ReentrantLock(); + + private final ConcurrentHashMap waiting = new ConcurrentHashMap<>(); + private final ConcurrentHashMap responses = new ConcurrentHashMap<>(); + + private AtomicInteger idCounter = new AtomicInteger(); + + public Consumer allEventHandler = (o) -> { + }; + + public RPCLayer(Reader incoming, Writer outgoing) { + this.incoming = new BufferedReader(incoming); + this.outgoing = outgoing; + threadListener = new Thread(this::listenForEvents); + threadListener.start(); + } + + public static RPCLayer startWithCLI(String jarFile) throws IOException { + var pbuilder = new ProcessBuilder("java", "-jar", jarFile); + var p = pbuilder.start(); + var incoming = new InputStreamReader(p.getInputStream()); + var outgoing = new OutputStreamWriter(p.getOutputStream()); + return new RPCLayer(incoming, outgoing); + } + + private void listenForEvents() { + char[] buf = new char[4 * 1024]; + try { + while (true) { + String length = incoming.readLine(); + if (length == null) { + break; // connection closed + } + + if (!length.startsWith("Content-Length: ")) { + break;//communication mismatch + } + + int len = Integer.parseInt(length.substring(17)); + + if (buf.length <= len + 2) {//also read \r\n, + buf = new char[len + 2]; //reallocate more + } + + int count = incoming.read(buf); + assert count == buf.length; + + var message = new String(buf, 0, count); + processIncomingMessage(message); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void processIncomingMessage(String message) { + var simpleMap = gson.fromJson(message, Map.class); + } + + public Object waitForResponse(String id) throws InterruptedException { + var cond = waiting.get(id); + cond.wait(); + return responses.get(id); + } + + public Object callSync(String methodName, Object... args) throws InterruptedException, IOException { + var id = nextId(); + waiting.put(id, new Object()); + sendAsync(id, methodName, args); + return waitForResponse(id); + } + + public void callAsync(String methodName, Object... args) throws IOException { + var id = nextId(); + sendAsync(id, methodName, args); + } + + private String nextId() { + return "" + idCounter.getAndIncrement(); + } + + private void sendAsync(String id, String methodName, Object[] args) throws IOException { + try { + lockSend.lock(); + var map = Map.of("id", id, "method", methodName, "args", args); + var json = gson.toJson(map); + outgoing.write("Content-Length: %d\r\n".formatted(json.length())); + outgoing.write(json); + outgoing.write("\r\n"); + outgoing.flush(); + } finally { + lockSend.unlock(); + } + } +} \ No newline at end of file diff --git a/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/TreeNodeId.java b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/TreeNodeId.java new file mode 100644 index 00000000000..30050fd6b85 --- /dev/null +++ b/keyext.client.java/src/main/java/edu/kit/iti/formal/keyextclientjava/TreeNodeId.java @@ -0,0 +1,8 @@ +package edu.kit.iti.formal.keyextclientjava; + +/** + * @author Alexander Weigl + * @version 1 (22.11.24) + */ +public record TreeNodeId() { +} diff --git a/keyext.client.java/src/main/resources/edu/kit/iti/formal/keyextclientjava/hello-view.fxml b/keyext.client.java/src/main/resources/edu/kit/iti/formal/keyextclientjava/hello-view.fxml new file mode 100644 index 00000000000..982318240d9 --- /dev/null +++ b/keyext.client.java/src/main/resources/edu/kit/iti/formal/keyextclientjava/hello-view.fxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + +