From 6316dbc4d638ae00b7ea3ac1216da36c633ad764 Mon Sep 17 00:00:00 2001
From: Alexander Weigl
Date: Thu, 12 Feb 2026 23:21:06 +0100
Subject: [PATCH 01/11] put CachingExtension into the correct service file.
---
.../services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension | 1 -
.../services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
create mode 100644 keyext.caching/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
diff --git a/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension b/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
index 3906585323c..fff85bf2d6d 100644
--- a/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
+++ b/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
@@ -6,7 +6,6 @@ de.uka.ilkd.key.gui.KeyboardTacletExtension
de.uka.ilkd.key.gui.nodeviews.ShowHashcodesExtension
de.uka.ilkd.key.gui.LogView
de.uka.ilkd.key.gui.plugins.javac.JavacExtension
-de.uka.ilkd.key.gui.plugins.caching.CachingExtension
de.uka.ilkd.key.gui.utilities.HeapStatusExt
de.uka.ilkd.key.gui.JmlEnabledKeysIndicator
de.uka.ilkd.key.gui.extension.impl.ProfileNameInStatusBar
\ No newline at end of file
diff --git a/keyext.caching/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension b/keyext.caching/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
new file mode 100644
index 00000000000..37763eb246e
--- /dev/null
+++ b/keyext.caching/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
@@ -0,0 +1 @@
+de.uka.ilkd.key.gui.plugins.caching.CachingExtension
From 09ce971e712e28addf147f3155cfefee49ae0ef8 Mon Sep 17 00:00:00 2001
From: Alexander Weigl
Date: Fri, 13 Feb 2026 00:43:59 +0100
Subject: [PATCH 02/11] adding the possibility to have a Profile-dependent
option panel
---
.../java/de/uka/ilkd/key/wd/WdProfile.java | 11 +-
.../key/proof/init/ProblemInitializer.java | 77 ++++----
.../de/uka/ilkd/key/proof/init/Profile.java | 3 +-
.../key/proof/io/AbstractProblemLoader.java | 173 ++++++++++--------
.../key/gui/KeYFileChooserLoadingOptions.java | 26 ++-
.../ilkd/key/gui/actions/OpenFileAction.java | 5 +-
.../gui/extension/api/KeYGuiExtension.java | 22 ++-
.../extension/impl/KeYGuiExtensionFacade.java | 14 ++
.../WDLoadDialogOptionPanel.java | 107 +++++++++++
...ilkd.key.gui.extension.api.KeYGuiExtension | 3 +-
10 files changed, 314 insertions(+), 127 deletions(-)
create mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java
diff --git a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java
index e5f650a2b08..af7362b3190 100644
--- a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java
+++ b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java
@@ -17,6 +17,7 @@
import de.uka.ilkd.key.rule.*;
import de.uka.ilkd.key.util.KeYResourceManager;
+import org.jspecify.annotations.Nullable;
import org.key_project.logic.Name;
import org.key_project.util.collection.ImmutableList;
@@ -97,9 +98,17 @@ public RuleCollection getStandardRules() {
return wdStandardRules;
}
+ ///
+ /// @param baseConfig
+ /// @param additionalProfileOptions a string representing the choice of `wdOperator`
@Override
- public void prepareInitConfig(InitConfig baseConfig) {
+ public void prepareInitConfig(InitConfig baseConfig, @Nullable Object additionalProfileOptions) {
var wdChoice = baseConfig.choiceNS().lookup(new Name("wdChecks:on"));
baseConfig.activateChoice(wdChoice);
+
+ if (additionalProfileOptions != null) {
+ var wdOperator = baseConfig.choiceNS().lookup(new Name(additionalProfileOptions.toString()));
+ baseConfig.activateChoice(wdOperator);
+ }
}
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java
index 1b7b6fa1ed0..905eba2e6eb 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java
@@ -39,6 +39,7 @@
import de.uka.ilkd.key.util.MiscTools;
import de.uka.ilkd.key.util.ProgressMonitor;
+import org.jspecify.annotations.Nullable;
import org.key_project.logic.Namespace;
import org.key_project.logic.Term;
import org.key_project.logic.op.Function;
@@ -68,26 +69,34 @@ public final class ProblemInitializer {
*/
private FileRepo fileRepo;
private ImmutableSet warnings = DefaultImmutableSet.nil();
+ private @Nullable Object additionalProfileOptions;
// -------------------------------------------------------------------------
// constructors
// -------------------------------------------------------------------------
public ProblemInitializer(ProgressMonitor mon, Services services,
- ProblemInitializerListener listener) {
+ ProblemInitializerListener listener) {
this.services = services;
this.progMon = mon;
this.listener = listener;
}
public ProblemInitializer(Profile profile) {
- if (profile == null) {
- throw new IllegalArgumentException("Given profile is null");
- }
+ this(null, new Services(Objects.requireNonNull(profile, "Given profile is null")), null);
+ }
+
+ public ProblemInitializer(Profile profile, @Nullable Object additionalProfileOptions) {
+ this(profile);
+ this.additionalProfileOptions = additionalProfileOptions;
+ }
- this.progMon = null;
- this.listener = null;
- this.services = new Services(Objects.requireNonNull(profile));
+ public @Nullable Object getAdditionalProfileOptions() {
+ return additionalProfileOptions;
+ }
+
+ public void setAdditionalProfileOptions(@Nullable Object additionalProfileOptions) {
+ this.additionalProfileOptions = additionalProfileOptions;
}
private void progressStarted(Object sender) {
@@ -127,7 +136,7 @@ private void reportStatus(String status) {
/**
* displays the status report in the status line and the maximum used by a progress bar
*
- * @param status the String to be displayed in the status line
+ * @param status the String to be displayed in the status line
* @param progressMax an int describing what is 100 per cent
*/
private void reportStatus(String status, int progressMax) {
@@ -166,7 +175,7 @@ private void readLDTIncludes(Includes in, InitConfig initConfig) throws ProofInp
for (String name : in.getLDTIncludes()) {
keyFile[i] =
- new KeYFile(name, in.get(name), progMon, initConfig.getProfile(), fileRepo);
+ new KeYFile(name, in.get(name), progMon, initConfig.getProfile(), fileRepo);
i++;
setProgress(i);
}
@@ -196,7 +205,7 @@ private void readIncludes(EnvInput envInput, InitConfig initConfig) throws Proof
int i = 0;
for (String fileName : in.getIncludes()) {
KeYFile keyFile =
- new KeYFile(fileName, in.get(fileName), progMon, envInput.getProfile(), fileRepo);
+ new KeYFile(fileName, in.get(fileName), progMon, envInput.getProfile(), fileRepo);
readEnvInput(keyFile, initConfig);
setProgress(++i);
}
@@ -212,11 +221,11 @@ private Collection getClasses(Path javaRoot) throws ProofInputException {
return walker.filter(it -> it.getFileName().toString().endsWith(".java")).toList();
} catch (IOException e) {
throw new ProofInputException(
- "Reading java model path " + javaRoot + " resulted into an error.", e);
+ "Reading java model path " + javaRoot + " resulted into an error.", e);
}
} else {
throw new ProofInputException(
- "Java model path " + javaRoot + " not found or is not a directory.");
+ "Java model path " + javaRoot + " not found or is not a directory.");
}
}
@@ -247,8 +256,8 @@ private void readJava(EnvInput envInput, InitConfig initConfig) throws ProofInpu
// this allows to use included symbols inside JML.
for (var fileName : includes.getRuleSets()) {
KeYFile keyFile =
- new KeYFile(fileName.file().getFileName().toString(), fileName, progMon,
- envInput.getProfile(), fileRepo);
+ new KeYFile(fileName.file().getFileName().toString(), fileName, progMon,
+ envInput.getProfile(), fileRepo);
readEnvInput(keyFile, initConfig);
}
@@ -286,7 +295,7 @@ private void readJava(EnvInput envInput, InitConfig initConfig) throws ProofInpu
}
var initialFile = envInput.getInitialFile();
initConfig.getServices().setJavaModel(
- JavaModel.createJavaModel(javaPath, classPath, bootClassPath, includes, initialFile));
+ JavaModel.createJavaModel(javaPath, classPath, bootClassPath, includes, initialFile));
}
/**
@@ -333,7 +342,7 @@ public void readEnvInput(EnvInput envInput, InitConfig initConfig) throws ProofI
}
private void populateNamespaces(Term term, NamespaceSet namespaces,
- Goal rootGoal) {
+ Goal rootGoal) {
for (int i = 0; i < term.arity(); i++) {
populateNamespaces(term.sub(i), namespaces, rootGoal);
}
@@ -353,7 +362,7 @@ private void populateNamespaces(Term term, NamespaceSet namespaces,
final ProgramElement pe = mod.programBlock().program();
final Services serv = rootGoal.proof().getServices();
final ImmutableSet freeProgVars =
- MiscTools.getLocalIns(pe, serv).union(MiscTools.getLocalOuts(pe, serv));
+ MiscTools.getLocalIns(pe, serv).union(MiscTools.getLocalOuts(pe, serv));
for (ProgramVariable pv : freeProgVars) {
if (namespaces.programVariables().lookup(pv.name()) == null) {
rootGoal.addProgramVariable(pv);
@@ -378,7 +387,7 @@ private void populateNamespaces(Proof proof) {
private InitConfig determineEnvironment(ProofOblInput po, InitConfig initConfig) {
// TODO: what does this actually do?
ProofSettings.DEFAULT_SETTINGS.getChoiceSettings().updateChoices(initConfig.choiceNS(),
- false);
+ false);
return initConfig;
}
@@ -393,12 +402,12 @@ private void setUpProofHelper(ProofOblInput problem, ProofAggregate pl)
reportStatus("Registering rules", proofs.length * 10);
for (int i = 0; i < proofs.length; i++) {
proofs[i].getInitConfig().registerRules(proofs[i].getInitConfig().getTaclets(),
- AxiomJustification.INSTANCE);
+ AxiomJustification.INSTANCE);
setProgress(3 + i * proofs.length);
// register built in rules
Profile profile = proofs[i].getInitConfig().getProfile();
final ImmutableList rules =
- profile.getStandardRules().standardBuiltInRules();
+ profile.getStandardRules().standardBuiltInRules();
int j = 0;
final int step = rules.size() != 0 ? (7 / rules.size()) : 0;
for (Rule r : rules) {
@@ -442,15 +451,15 @@ public InitConfig prepare(EnvInput envInput) throws ProofInputException {
if (tacletBases != null) {
for (var tacletBase : tacletBases) {
KeYFile tacletBaseFile = new KeYFile(
- "taclet base (%s)".formatted(tacletBase.file().getFileName()),
- tacletBase, progMon, profile);
+ "taclet base (%s)".formatted(tacletBase.file().getFileName()),
+ tacletBase, progMon, profile, null);
readEnvInput(tacletBaseFile, currentBaseConfig);
}
}
// remove traces of the generic sorts within the base configuration
cleanupNamespaces(currentBaseConfig);
- profile.prepareInitConfig(currentBaseConfig);
+ profile.prepareInitConfig(currentBaseConfig, additionalProfileOptions);
baseConfig = currentBaseConfig;
}
@@ -473,7 +482,7 @@ private void print(Proof firstProof) {
}
LOGGER.debug("Taclets under: {}", taclets1);
try (PrintWriter out =
- new PrintWriter(new BufferedWriter(new FileWriter(taclets1, StandardCharsets.UTF_8)))) {
+ new PrintWriter(new BufferedWriter(new FileWriter(taclets1, StandardCharsets.UTF_8)))) {
out.print(firstProof.toString());
} catch (IOException e) {
LOGGER.warn("Failed write proof", e);
@@ -490,7 +499,7 @@ private void print(InitConfig ic) {
}
LOGGER.debug("Taclets under: {}", taclets1);
try (PrintWriter out =
- new PrintWriter(new BufferedWriter(new FileWriter(taclets1, StandardCharsets.UTF_8)))) {
+ new PrintWriter(new BufferedWriter(new FileWriter(taclets1, StandardCharsets.UTF_8)))) {
out.format("Date: %s%n", new Date());
out.format("Choices: %n");
@@ -501,7 +510,7 @@ private void print(InitConfig ic) {
taclets.sort(Comparator.comparing(a -> a.name().toString()));
for (Taclet taclet : taclets) {
out.format("== %s (%s) =========================================%n", taclet.name(),
- taclet.displayName());
+ taclet.displayName());
out.println(taclet);
out.format("-----------------------------------------------------%n");
}
@@ -516,10 +525,10 @@ private void print(InitConfig ic) {
private void configureTermLabelSupport(InitConfig initConfig) {
initConfig.getServices().setOriginFactory(
- ProofIndependentSettings.DEFAULT_INSTANCE.getTermLabelSettings()
- .getUseOriginLabels()
- ? new OriginTermLabelFactory()
- : null);
+ ProofIndependentSettings.DEFAULT_INSTANCE.getTermLabelSettings()
+ .getUseOriginLabels()
+ ? new OriginTermLabelFactory()
+ : null);
}
private InitConfig prepare(EnvInput envInput, InitConfig referenceConfig)
@@ -543,9 +552,8 @@ private InitConfig prepare(EnvInput envInput, InitConfig referenceConfig)
if (type instanceof ClassDeclaration || type instanceof InterfaceDeclaration) {
for (Field f : javaInfo.getAllFields((TypeDeclaration) type)) {
final ProgramVariable pv = (ProgramVariable) f.getProgramVariable();
- if (pv instanceof LocationVariable) {
- heapLDT.getFieldSymbolForPV((LocationVariable) pv,
- initConfig.getServices());
+ if (pv instanceof LocationVariable lv) {
+ heapLDT.getFieldSymbolForPV(lv, initConfig.getServices());
}
}
}
@@ -573,8 +581,7 @@ private InitConfig prepare(EnvInput envInput, InitConfig referenceConfig)
return initConfig;
}
- public ProofAggregate startProver(InitConfig initConfig, ProofOblInput po)
- throws ProofInputException {
+ public ProofAggregate startProver(InitConfig initConfig, ProofOblInput po) throws ProofInputException {
progressStarted(this);
try {
// determine environment
diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java
index 9316c659d0e..2195184cded 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java
@@ -14,6 +14,7 @@
import de.uka.ilkd.key.rule.UseOperationContractRule;
import de.uka.ilkd.key.strategy.StrategyFactory;
+import org.jspecify.annotations.Nullable;
import org.key_project.logic.Name;
import org.key_project.prover.engine.GoalChooserFactory;
import org.key_project.prover.proof.ProofGoal;
@@ -181,7 +182,7 @@ default UseOperationContractRule getUseOperationContractRule() {
/// established.
///
/// @see ProblemInitializer
- default void prepareInitConfig(InitConfig baseConfig) {
+ default void prepareInitConfig(InitConfig baseConfig, @Nullable Object additionalProfileOptions) {
}
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java b/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java
index 167aff7270c..822c11d3f4d 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java
@@ -64,36 +64,7 @@ public abstract class AbstractProblemLoader {
* @see EnvInput#isIgnoreOtherJavaFiles()
*/
private boolean loadSingleJavaFile = false;
-
- public static class ReplayResult {
-
- private final Node node;
- private final List errors;
- private final String status;
-
- public ReplayResult(String status, List errors, Node node) {
- this.status = status;
- this.errors = errors;
- this.node = node;
- }
-
- public Node getNode() {
- return node;
- }
-
- public String getStatus() {
- return status;
- }
-
- public List getErrorList() {
- return errors;
- }
-
- public boolean hasErrors() {
- return errors != null && !errors.isEmpty();
- }
-
- }
+ private Object additionalProfileOptions;
/**
* The file or folder to load.
@@ -191,7 +162,7 @@ public boolean hasErrors() {
static {
mismatchErrors.put(new Pair<>(KeYLexer.SEMI, KeYLexer.COMMA),
- "there may be only one declaration per line");
+ "there may be only one declaration per line");
missedErrors.put(KeYLexer.RPAREN, "closing parenthesis");
missedErrors.put(KeYLexer.RBRACE, "closing brace");
@@ -201,34 +172,34 @@ public boolean hasErrors() {
/**
* Constructor.
*
- * @param file The file or folder to load.
- * @param classPath The optional class path entries to use.
- * @param bootClassPath An optional boot class path.
- * @param includes Optional includes to consider.
- * @param profileOfNewProofs The {@link Profile} to use for new {@link Proof}s.
- * @param forceNewProfileOfNewProofs {@code} true {@link #profileOfNewProofs} will be used as
- * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file
- * will be used for new proofs.
- * @param control The {@link ProblemLoaderControl} to use.
+ * @param file The file or folder to load.
+ * @param classPath The optional class path entries to use.
+ * @param bootClassPath An optional boot class path.
+ * @param includes Optional includes to consider.
+ * @param profileOfNewProofs The {@link Profile} to use for new {@link Proof}s.
+ * @param forceNewProfileOfNewProofs {@code} true {@link #profileOfNewProofs} will be used as
+ * {@link Profile} of new proofs, {@code false} {@link Profile} specified by problem file
+ * will be used for new proofs.
+ * @param control The {@link ProblemLoaderControl} to use.
* @param askUiToSelectAProofObligationIfNotDefinedByLoadedFile {@code true} to call
- * {@link ProblemLoaderControl#selectProofObligation(InitConfig)} if no {@link Proof} is
- * defined by the loaded proof or {@code false} otherwise which still allows to work with
- * the loaded {@link InitConfig}.
+ * {@link ProblemLoaderControl#selectProofObligation(InitConfig)} if no {@link Proof} is
+ * defined by the loaded proof or {@code false} otherwise which still allows to work with
+ * the loaded {@link InitConfig}.
*/
protected AbstractProblemLoader(Path file, List classPath, Path bootClassPath,
- List includes, Profile profileOfNewProofs, boolean forceNewProfileOfNewProofs,
- ProblemLoaderControl control,
- boolean askUiToSelectAProofObligationIfNotDefinedByLoadedFile,
- Properties poPropertiesToForce) {
+ List includes, Profile profileOfNewProofs, boolean forceNewProfileOfNewProofs,
+ ProblemLoaderControl control,
+ boolean askUiToSelectAProofObligationIfNotDefinedByLoadedFile,
+ Properties poPropertiesToForce) {
this.file = file;
this.classPath = classPath;
this.bootClassPath = bootClassPath;
this.control = control;
setProfileOfNewProofs(
- profileOfNewProofs != null ? profileOfNewProofs : AbstractProfile.getDefaultProfile());
+ profileOfNewProofs != null ? profileOfNewProofs : AbstractProfile.getDefaultProfile());
this.forceNewProfileOfNewProofs = forceNewProfileOfNewProofs;
this.askUiToSelectAProofObligationIfNotDefinedByLoadedFile =
- askUiToSelectAProofObligationIfNotDefinedByLoadedFile;
+ askUiToSelectAProofObligationIfNotDefinedByLoadedFile;
this.poPropertiesToForce = poPropertiesToForce;
this.includes = includes;
}
@@ -313,8 +284,8 @@ protected void setProof(@Nullable Proof proof) {
* Executes the loading process and tries to instantiate a proof and to re-apply rules on it if
* possible.
*
- * @throws ProofInputException Occurred Exception.
- * @throws IOException Occurred Exception.
+ * @throws ProofInputException Occurred Exception.
+ * @throws IOException Occurred Exception.
* @throws ProblemLoaderException Occurred Exception.
*/
public final void load() throws Exception {
@@ -326,9 +297,9 @@ public final void load() throws Exception {
* possible.
*
* @param callbackProofLoaded optional callback, called when the proof is loaded but not yet
- * replayed
- * @throws ProofInputException Occurred Exception.
- * @throws IOException Occurred Exception.
+ * replayed
+ * @throws ProofInputException Occurred Exception.
+ * @throws IOException Occurred Exception.
* @throws ProblemLoaderException Occurred Exception.
*/
public final void load(Consumer callbackProofLoaded) throws Exception {
@@ -356,7 +327,7 @@ public final void load(Consumer callbackProofLoaded) throws Exception {
* Loads and initialized the proof environment.
*
* @throws ProofInputException Occurred Exception.
- * @throws IOException Occurred Exception.
+ * @throws IOException Occurred Exception.
* @see AbstractProblemLoader#load()
*/
protected void loadEnvironment() throws ProofInputException, IOException {
@@ -366,14 +337,14 @@ protected void loadEnvironment() throws ProofInputException, IOException {
LOGGER.info("Loading environment from {}", file);
envInput = createEnvInput(fileRepo);
LOGGER.debug("Environment load took {}",
- PerfScope.formatTime(System.nanoTime() - timeBeforeEnv));
+ PerfScope.formatTime(System.nanoTime() - timeBeforeEnv));
problemInitializer = createProblemInitializer(fileRepo);
var beforeInitConfig = System.nanoTime();
LOGGER.info("Creating init config");
initConfig = createInitConfig();
initConfig.setFileRepo(fileRepo);
LOGGER.debug("Init config took {}",
- PerfScope.formatTime(System.nanoTime() - beforeInitConfig));
+ PerfScope.formatTime(System.nanoTime() - beforeInitConfig));
if (!problemInitializer.getWarnings().isEmpty() && !ignoreWarnings) {
control.reportWarnings(problemInitializer.getWarnings());
}
@@ -382,7 +353,7 @@ protected void loadEnvironment() throws ProofInputException, IOException {
/**
* Asks the user to select a proof obligation and loads it.
*
- * @param control the ui controller.
+ * @param control the ui controller.
* @param initConfig the proof configuration.
* @see AbstractProblemLoader#load()
*/
@@ -393,13 +364,13 @@ protected void selectAndLoadProof(ProblemLoaderControl control, InitConfig initC
/**
* Loads a proof from the proof list.
*
- * @param poContainer the container created by {@link #createProofObligationContainer()}.
- * @param proofList the proof list containing the proof to load.
+ * @param poContainer the container created by {@link #createProofObligationContainer()}.
+ * @param proofList the proof list containing the proof to load.
* @param callbackProofLoaded optional callback, called before the proof is replayed
* @see AbstractProblemLoader#load()
*/
protected void loadSelectedProof(LoadedPOContainer poContainer, ProofAggregate proofList,
- Consumer callbackProofLoaded) {
+ Consumer callbackProofLoaded) {
// try to replay first proof
proof = proofList.getProof(poContainer.getProofNum());
@@ -419,7 +390,7 @@ protected void loadSelectedProof(LoadedPOContainer poContainer, ProofAggregate p
*
* @return a FileRepo that can be used for proof bundle saving
* @throws IOException if for some reason the FileRepo can not be created (e.g. temporary
- * directory can not be created).
+ * directory can not be created).
*/
protected FileRepo createFileRepo() throws IOException {
// create a FileRepo depending on the settings
@@ -452,10 +423,10 @@ protected EnvInput createEnvInput(FileRepo fileRepo) throws IOException {
SLEnvInput ret;
if (file.getParent() == null) {
ret = new SLEnvInput(Paths.get("."), classPath, bootClassPath, profileOfNewProofs,
- includes);
+ includes);
} else {
ret = new SLEnvInput(file.getParent().toAbsolutePath(), classPath,
- bootClassPath, profileOfNewProofs, includes);
+ bootClassPath, profileOfNewProofs, includes);
}
ret.setJavaFile(file.toAbsolutePath());
ret.setIgnoreOtherJavaFiles(loadSingleJavaFile);
@@ -520,12 +491,12 @@ protected EnvInput createEnvInput(FileRepo fileRepo) throws IOException {
Path unzippedProof = tmpDir.resolve(proofFilename);
return new KeYUserProblemFile(unzippedProof.toString(), unzippedProof,
- fileRepo, control, profileOfNewProofs, false);
+ fileRepo, control, profileOfNewProofs, false);
} else if (filename.endsWith(".key") || filename.endsWith(".proof")
|| filename.endsWith(".proof.gz")) {
// KeY problem specification or saved proof
return new KeYUserProblemFile(filename, file, fileRepo, control, profileOfNewProofs,
- filename.endsWith(".proof.gz"));
+ filename.endsWith(".proof.gz"));
} else if (Files.isDirectory(file)) {
// directory containing java sources, probably enriched
// by specifications
@@ -533,12 +504,12 @@ protected EnvInput createEnvInput(FileRepo fileRepo) throws IOException {
} else {
if (filename.lastIndexOf('.') != -1) {
throw new IllegalArgumentException("Unsupported file extension '"
- + filename.substring(filename.lastIndexOf('.')) + "' of read-in file "
- + filename + ". Allowed extensions are: .key, .proof, .java or "
- + "complete directories.");
+ + filename.substring(filename.lastIndexOf('.')) + "' of read-in file "
+ + filename + ". Allowed extensions are: .key, .proof, .java or "
+ + "complete directories.");
} else {
throw new FileNotFoundException(
- "File or directory\n\t " + filename + "\n not found.");
+ "File or directory\n\t " + filename + "\n not found.");
}
}
}
@@ -552,6 +523,7 @@ protected EnvInput createEnvInput(FileRepo fileRepo) throws IOException {
protected ProblemInitializer createProblemInitializer(FileRepo fileRepo) {
Profile profile = forceNewProfileOfNewProofs ? profileOfNewProofs : envInput.getProfile();
ProblemInitializer pi = new ProblemInitializer(control, new Services(profile), control);
+ pi.setAdditionalProfileOptions(additionalProfileOptions);
pi.setFileRepo(fileRepo);
return pi;
}
@@ -610,17 +582,17 @@ private LoadedPOContainer loadByProofObligation(Configuration proofObligation)
String poClass = proofObligation.getString(IPersistablePO.PROPERTY_CLASS);
if (poClass == null || poClass.isEmpty()) {
throw new IOException("Proof obligation class property \""
- + IPersistablePO.PROPERTY_CLASS + "\" is not defiend or empty.");
+ + IPersistablePO.PROPERTY_CLASS + "\" is not defiend or empty.");
}
ServiceLoader loader =
- ServiceLoader.load(ProofObligationLoader.class);
+ ServiceLoader.load(ProofObligationLoader.class);
for (ProofObligationLoader poloader : loader) {
if (poloader.handles(poClass)) {
return poloader.loadFrom(initConfig, proofObligation);
}
}
throw new IllegalArgumentException(
- "There is no builder that can build the PO for the id " + poClass);
+ "There is no builder that can build the PO for the id " + poClass);
}
private LoadedPOContainer loadByChosenContract(String chooseContract) {
@@ -660,7 +632,7 @@ private LoadedPOContainer loadByChosenContract(String chooseContract) {
protected ProofAggregate createProof(LoadedPOContainer poContainer) throws ProofInputException {
ProofAggregate proofList =
- problemInitializer.startProver(initConfig, poContainer.getProofOblInput());
+ problemInitializer.startProver(initConfig, poContainer.getProofOblInput());
for (Proof p : proofList.getProofs()) {
// register proof
@@ -711,7 +683,7 @@ private ReplayResult replayProof(Proof proof) {
assert envInput instanceof KeYUserProblemFile;
IntermediatePresentationProofFileParser parser =
- new IntermediatePresentationProofFileParser(proof);
+ new IntermediatePresentationProofFileParser(proof);
problemInitializer.tryReadProof(parser, (KeYUserProblemFile) envInput);
parserResult = parser.getResult();
@@ -722,14 +694,14 @@ private ReplayResult replayProof(Proof proof) {
// able to load proofs that used it even if the user has currently
// turned OSS off.
StrategyProperties newProps =
- proof.getSettings().getStrategySettings().getActiveStrategyProperties();
+ proof.getSettings().getStrategySettings().getActiveStrategyProperties();
newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, StrategyProperties.OSS_ON);
Strategy.updateStrategySettings(proof, newProps);
OneStepSimplifier.refreshOSS(proof);
replayer = new IntermediateProofReplayer(this, proof, parserResult);
replayResult =
- replayer.replay(problemInitializer.getListener(), problemInitializer.getProgMon());
+ replayer.replay(problemInitializer.getListener(), problemInitializer.getProgMon());
lastTouchedNode = replayResult.getLastSelectedGoal() != null
? replayResult.getLastSelectedGoal().node()
@@ -750,13 +722,13 @@ private ReplayResult replayProof(Proof proof) {
}
status += (status.isEmpty() ? "Proof replayed successfully." : "\n\n")
+ (replayResult != null ? replayResult.getStatus()
- : "Error while loading proof.");
+ : "Error while loading proof.");
if (replayResult != null) {
errors.addAll(replayResult.getErrors());
}
StrategyProperties newProps =
- proof.getSettings().getStrategySettings().getActiveStrategyProperties();
+ proof.getSettings().getStrategySettings().getActiveStrategyProperties();
newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, ossStatus);
Strategy.updateStrategySettings(proof, newProps);
OneStepSimplifier.refreshOSS(proof);
@@ -818,7 +790,7 @@ public ProblemInitializer getProblemInitializer() {
* elements and specifications.
*
* @return The instantiated {@link InitConfig} which provides access to the loaded source
- * elements and specifications.
+ * elements and specifications.
*/
public InitConfig getInitConfig() {
return initConfig;
@@ -829,7 +801,7 @@ public InitConfig getInitConfig() {
* process.
*
* @return The instantiate proof or {@code null} if no proof was instantiated during loading
- * process.
+ * process.
*/
public Proof getProof() {
return proof;
@@ -859,4 +831,43 @@ public void setLoadSingleJavaFile(boolean loadSingleJavaFile) {
public void setIgnoreWarnings(boolean ignoreWarnings) {
this.ignoreWarnings = ignoreWarnings;
}
+
+ public void setAdditionalProfileOptions(Object additionalProfileOptions) {
+ this.additionalProfileOptions = additionalProfileOptions;
+ }
+
+ public Object getAdditionalProfileOptions() {
+ return additionalProfileOptions;
+ }
+
+
+ public static class ReplayResult {
+
+ private final Node node;
+ private final List errors;
+ private final String status;
+
+ public ReplayResult(String status, List errors, Node node) {
+ this.status = status;
+ this.errors = errors;
+ this.node = node;
+ }
+
+ public Node getNode() {
+ return node;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public List getErrorList() {
+ return errors;
+ }
+
+ public boolean hasErrors() {
+ return errors != null && !errors.isEmpty();
+ }
+
+ }
}
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java
index c6e35409d7e..52260d0eecc 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java
@@ -3,11 +3,11 @@
* SPDX-License-Identifier: GPL-2.0-only */
package de.uka.ilkd.key.gui;
-import java.util.Arrays;
-import java.util.Objects;
-import java.util.ServiceLoader;
+import java.util.*;
import javax.swing.*;
+import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension;
+import de.uka.ilkd.key.gui.extension.impl.KeYGuiExtensionFacade;
import de.uka.ilkd.key.gui.settings.SettingsPanel;
import de.uka.ilkd.key.proof.init.AbstractProfile;
import de.uka.ilkd.key.proof.init.DefaultProfileResolver;
@@ -39,6 +39,11 @@ public class KeYFileChooserLoadingOptions extends JPanel {
Mark this checkbox to only load the selected Java file.
""");
+ private final Map additionalOptionPanels =
+ KeYGuiExtensionFacade.createAdditionalOptionPanels();
+
+
+ private KeYGuiExtension.@Nullable OptionPanel currentOptionPanel = null;
public KeYFileChooserLoadingOptions(KeYFileChooser chooser) {
setLayout(new MigLayout(new LC().fillX().wrapAfter(3).maxWidth("400"),
@@ -78,10 +83,18 @@ private void updateProfileInfo() {
}
private void updateProfileInfo(@Nullable ProfileWrapper selectedItem) {
+ if(currentOptionPanel!=null){currentOptionPanel.deinstall(this);}
+
if (selectedItem == null) {
lblProfileInfo.setText("");
} else {
lblProfileInfo.setText(selectedItem.profile.description());
+
+
+ if (additionalOptionPanels.containsKey(selectedItem.profile)) {
+ currentOptionPanel = additionalOptionPanels.get(selectedItem.profile);
+ currentOptionPanel.install(this);
+ }
}
}
@@ -94,6 +107,13 @@ private void updateProfileInfo(@Nullable ProfileWrapper selectedItem) {
.orElse(null);
}
+ public @Nullable Object getAdditionalProfileOptions() {
+ if(currentOptionPanel==null){
+ return null;
+ }
+ return currentOptionPanel.getResult();
+ }
+
public @Nullable String getSelectedProfileName() {
return ((ProfileWrapper) cboProfile.getSelectedItem()).profile().ident();
}
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java
index c0682f40938..aa2393717b2 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java
@@ -10,6 +10,7 @@
import de.uka.ilkd.key.core.Main;
import de.uka.ilkd.key.gui.KeYFileChooser;
+import de.uka.ilkd.key.gui.KeYFileChooserLoadingOptions;
import de.uka.ilkd.key.gui.MainWindow;
import de.uka.ilkd.key.gui.ProofSelectionDialog;
import de.uka.ilkd.key.gui.fonticons.IconFactory;
@@ -29,7 +30,7 @@ public OpenFileAction(MainWindow mainWindow) {
public void actionPerformed(ActionEvent e) {
KeYFileChooser fc = new KeYFileChooser(lastSelectedPath);
fc.setDialogTitle("Select file to load proof or problem");
- var options = fc.addLoadingOptions();
+ KeYFileChooserLoadingOptions options = fc.addLoadingOptions();
fc.addBookmarkPanel();
fc.prepare();
fc.setFileFilter(KeYFileChooser.DEFAULT_FILTER);
@@ -64,9 +65,11 @@ public void actionPerformed(ActionEvent e) {
}
var selectedProfile = options.getSelectedProfile();
+ var additionalProfileOptions = options.getAdditionalProfileOptions();
mainWindow.loadProblem(file, pl -> {
if (selectedProfile != null) {
pl.setProfileOfNewProofs(selectedProfile);
+ pl.setAdditionalProfileOptions(additionalProfileOptions);
}
pl.setLoadSingleJavaFile(options.isOnlyLoadSingleJavaFile());
});
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java
index ef94d9dc7df..fa542a160fb 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java
@@ -7,16 +7,14 @@
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.List;
+import java.util.function.Supplier;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JToolBar;
import de.uka.ilkd.key.core.KeYMediator;
-import de.uka.ilkd.key.gui.GoalList;
-import de.uka.ilkd.key.gui.InfoView;
-import de.uka.ilkd.key.gui.MainWindow;
-import de.uka.ilkd.key.gui.StrategySelectionView;
+import de.uka.ilkd.key.gui.*;
import de.uka.ilkd.key.gui.keyshortcuts.KeyStrokeManager;
import de.uka.ilkd.key.gui.nodeviews.SequentView;
import de.uka.ilkd.key.gui.prooftree.ProofTreeView;
@@ -24,6 +22,7 @@
import de.uka.ilkd.key.gui.sourceview.SourceView;
import de.uka.ilkd.key.pp.PosInSequent;
+import de.uka.ilkd.key.proof.init.Profile;
import org.jspecify.annotations.NonNull;
/**
@@ -272,4 +271,19 @@ default int getTermLabelPriority() {
return 0;
}
}
+
+ ///
+ public interface LoadOptionPanel extends Supplier {
+ Profile getProfile();
+ }
+
+ /// A panel for additional options of profiles.
+ /// @author weigl
+ interface OptionPanel {
+ void install(KeYFileChooserLoadingOptions panel);
+
+ void deinstall(KeYFileChooserLoadingOptions panel);
+
+ Object getResult();
+ }
}
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java
index 199a32b428d..2840af2a526 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java
@@ -20,6 +20,7 @@
import de.uka.ilkd.key.gui.extension.api.TabPanel;
import de.uka.ilkd.key.pp.PosInSequent;
import de.uka.ilkd.key.proof.Proof;
+import de.uka.ilkd.key.proof.init.Profile;
/**
* Facade for retrieving the GUI extensions.
@@ -403,6 +404,19 @@ public static Stream getTermInfoStrings(MainWindow mainWindow, PosInSequ
.flatMap(it -> it.getTermInfoStrings(mainWindow, mousePos).stream());
}
+ /**
+ * TODO
+ * @return
+ */
+ public static Map createAdditionalOptionPanels() {
+ List items = getExtensionInstances(KeYGuiExtension.LoadOptionPanel.class);
+ HashMap map = HashMap.newHashMap(4);
+ for (KeYGuiExtension.LoadOptionPanel item : items) {
+ map.put(item.getProfile(), item.get());
+ }
+ return map;
+ }
+
/**
* Disables the clazz from further loading.
*
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java
new file mode 100644
index 00000000000..e8aa768a814
--- /dev/null
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java
@@ -0,0 +1,107 @@
+package de.uka.ilkd.key.gui.profileloading;
+
+import de.uka.ilkd.key.gui.KeYFileChooserLoadingOptions;
+import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension;
+import de.uka.ilkd.key.proof.init.Profile;
+import de.uka.ilkd.key.wd.WdProfile;
+import net.miginfocom.layout.CC;
+
+import javax.swing.*;
+import java.awt.*;
+
+@KeYGuiExtension.Info(experimental = false)
+public class WDLoadDialogOptionPanel implements KeYGuiExtension, KeYGuiExtension.LoadOptionPanel {
+ @Override
+ public OptionPanel get() {
+ return new WDLoadDialogOptionPanelImpl();
+ }
+
+ @Override
+ public Profile getProfile() {
+ return WdProfile.INSTANCE;
+ }
+
+ public static class WDLoadDialogOptionPanelImpl implements OptionPanel {
+ private final JRadioButton rdbWDL = new JRadioButton("L");
+ private final JRadioButton rdbWDY = new JRadioButton("Y");
+ private final JRadioButton rdbWDD = new JRadioButton("D");
+
+ private final JLabel lblHeader = new JLabel("WD options");
+ private final JLabel lblSemantics = new JLabel("Semantics:");
+ private final JSeparator sepHeader = new JSeparator();
+
+ private static final String DESCRIPTION_L_WD_SEMANTIC = """
+ More intuitive for software developers and along the lines of
+ runtime assertion semantics. Well-Definedness checks will be
+ stricter using this operator, since the order of terms/formulas
+ matters. It is based on McCarthy logic.
+ Cf. "Are the Logical Foundations of Verifying Compiler
+ Prototypes Matching User Expectations?" by Patrice Chalin.
+ """;
+
+ private static final String DESCRIPTION_D_WD_SEMANTIC = """
+ Complete and along the lines of classical logic, where the
+ order of terms/formulas is irrelevant. This operator is
+ equivalent to the D-operator, but more efficient.
+ Cf. "Efficient Well-Definedness Checking" by Ádám Darvas,
+ Farhad Mehta, and Arsenii Rudich.
+ """;
+
+
+ private static final String DESCRIPTION_Y_WD_SEMANTIC = """
+ Complete and along the lines of classical logic, where the
+ order of terms/formulas is irrelevant. This operator is not as
+ strict as the L-operator, based on strong Kleene logic. To be
+ used with care, since formulas may blow up exponentially.
+ Cf. "Well Defined B" by Patrick Behm, Lilian Burdy, and
+ Jean-Marc Meynadier
+ """;
+
+ public WDLoadDialogOptionPanelImpl() {
+ lblHeader.setFont(lblHeader.getFont().deriveFont(Font.BOLD));
+
+ rdbWDL.setToolTipText(DESCRIPTION_L_WD_SEMANTIC);
+ rdbWDD.setToolTipText(DESCRIPTION_D_WD_SEMANTIC);
+ rdbWDY.setToolTipText(DESCRIPTION_Y_WD_SEMANTIC);
+
+ ButtonGroup btnGrp = new ButtonGroup();
+ btnGrp.add(rdbWDD);
+ btnGrp.add(rdbWDL);
+ btnGrp.add(rdbWDY);
+
+ rdbWDL.setSelected(true);
+ }
+
+ @Override
+ public void install(KeYFileChooserLoadingOptions panel) {
+ panel.add(lblHeader);
+ panel.add(sepHeader, new CC().wrap().span(2).growX());
+
+ panel.add(lblSemantics);
+ panel.add(rdbWDD, new CC().span(2).split(3));
+ panel.add(rdbWDY);
+ panel.add(rdbWDL);
+ }
+
+ @Override
+ public void deinstall(KeYFileChooserLoadingOptions panel) {
+ panel.remove(lblHeader);
+ panel.remove(sepHeader);
+ panel.remove(rdbWDL);
+ panel.remove(rdbWDD);
+ panel.remove(rdbWDY);
+ }
+
+ @Override
+ public Object getResult() {
+ if (rdbWDD.isSelected()) {
+ return "wdOperator:D";
+ }
+ if (rdbWDY.isSelected()) {
+ return "wdOperator:Y";
+ }
+ // default
+ return "wdOperator:L";
+ }
+ }
+}
diff --git a/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension b/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
index fff85bf2d6d..646d2f4c102 100644
--- a/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
+++ b/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension
@@ -8,4 +8,5 @@ de.uka.ilkd.key.gui.LogView
de.uka.ilkd.key.gui.plugins.javac.JavacExtension
de.uka.ilkd.key.gui.utilities.HeapStatusExt
de.uka.ilkd.key.gui.JmlEnabledKeysIndicator
-de.uka.ilkd.key.gui.extension.impl.ProfileNameInStatusBar
\ No newline at end of file
+de.uka.ilkd.key.gui.extension.impl.ProfileNameInStatusBar
+de.uka.ilkd.key.gui.profileloading.WDLoadDialogOptionPanel
\ No newline at end of file
From ad52e038c973b248507cc5bab18cc1dce25ac5c1 Mon Sep 17 00:00:00 2001
From: Alexander Weigl
Date: Sat, 14 Feb 2026 18:07:10 +0100
Subject: [PATCH 03/11] add javadoc
---
.../java/de/uka/ilkd/key/wd/WdProfile.java | 2 +-
.../key/proof/init/ProblemInitializer.java | 1 +
.../de/uka/ilkd/key/proof/init/Profile.java | 2 ++
.../key/proof/io/AbstractProblemLoader.java | 2 ++
.../gui/extension/api/KeYGuiExtension.java | 22 ++++++++++--
.../extension/impl/KeYGuiExtensionFacade.java | 34 ++++++++++---------
.../WDLoadDialogOptionPanel.java | 15 ++++----
7 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java
index af7362b3190..c00ec03ae6f 100644
--- a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java
+++ b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java
@@ -98,8 +98,8 @@ public RuleCollection getStandardRules() {
return wdStandardRules;
}
+ /// {@inheritDoc}
///
- /// @param baseConfig
/// @param additionalProfileOptions a string representing the choice of `wdOperator`
@Override
public void prepareInitConfig(InitConfig baseConfig, @Nullable Object additionalProfileOptions) {
diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java
index 905eba2e6eb..b667703bd9f 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java
@@ -91,6 +91,7 @@ public ProblemInitializer(Profile profile, @Nullable Object additionalProfileOpt
this.additionalProfileOptions = additionalProfileOptions;
}
+ /// An arbitrary object which is passed to the provided profile, during construction of the `initConfig`.
public @Nullable Object getAdditionalProfileOptions() {
return additionalProfileOptions;
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java
index 2195184cded..4075b48bca2 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java
@@ -181,6 +181,8 @@ default UseOperationContractRule getUseOperationContractRule() {
/// Taclet base has been loaded, but before Java sources are loaded or the environment is
/// established.
///
+ /// @param baseConfig a initial configuration which can be modified, e.g., forcing Taclet options.
+ /// @param additionalProfileOptions a nullable object representing selected options in the UI or command line.
/// @see ProblemInitializer
default void prepareInitConfig(InitConfig baseConfig, @Nullable Object additionalProfileOptions) {
diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java b/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java
index 822c11d3f4d..8615f408ca8 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java
@@ -836,6 +836,8 @@ public void setAdditionalProfileOptions(Object additionalProfileOptions) {
this.additionalProfileOptions = additionalProfileOptions;
}
+ /// An arbitrary object representing additional options for the given profile.
+ /// @see ProblemInitializer
public Object getAdditionalProfileOptions() {
return additionalProfileOptions;
}
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java
index fa542a160fb..d7ffc208f02 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java
@@ -22,6 +22,7 @@
import de.uka.ilkd.key.gui.sourceview.SourceView;
import de.uka.ilkd.key.pp.PosInSequent;
+import de.uka.ilkd.key.proof.init.InitConfig;
import de.uka.ilkd.key.proof.init.Profile;
import org.jspecify.annotations.NonNull;
@@ -272,18 +273,35 @@ default int getTermLabelPriority() {
}
}
+ /// A {@link LoadOptionPanel} provides additional UI components in the file selection dialog
+ /// dependent on the selected profile.
///
- public interface LoadOptionPanel extends Supplier {
+ /// Implementing this interface requires to provide an {@link OptionPanel}, and associated {@link Profile}.
+ ///
+ /// @author weigl
+ interface LoadOptionPanel extends Supplier {
Profile getProfile();
}
- /// A panel for additional options of profiles.
+ /// A provider of UI components for additional options w.r.t. specific profiles.
+ /// **Lifecycle:** For each {@link Profile} an {@link OptionPanel} is constructed, when the {@link KeYFileChooser}
+ /// is instantiated. *On selected of a profile*, the current {@link OptionPanel} is `deinstall`ed, and the
+ /// {@link OptionPanel} for the selected profile is `install`ed.
+ ///
/// @author weigl
+ /// @see KeYFileChooserLoadingOptions
interface OptionPanel {
+ /// Installs the UI components in the given {@link KeYFileChooserLoadingOptions} instance. UI components
+ /// can be reused, to keep the temporary state.
+ /// {@link KeYFileChooserLoadingOptions} uses the {@link net.miginfocom.swing.MigLayout} to manage the layout.
void install(KeYFileChooserLoadingOptions panel);
+ /// Removes all *installed* UI components from the panel.
void deinstall(KeYFileChooserLoadingOptions panel);
+ /// Returning an arbitrary object, representing the selected option in the UI components.
+ /// The object needs to compatible with the assigned profile in {@link LoadOptionPanel}.
+ /// @see Profile#prepareInitConfig(InitConfig, Object)
Object getResult();
}
}
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java
index 2840af2a526..25546baaa3f 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java
@@ -17,6 +17,8 @@
import de.uka.ilkd.key.gui.actions.KeyAction;
import de.uka.ilkd.key.gui.extension.api.ContextMenuKind;
import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension;
+import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension.LoadOptionPanel;
+import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension.OptionPanel;
import de.uka.ilkd.key.gui.extension.api.TabPanel;
import de.uka.ilkd.key.pp.PosInSequent;
import de.uka.ilkd.key.proof.Proof;
@@ -231,13 +233,13 @@ public static List getContextMenuExtensions() {
* If the underlying object is a proof, this will also include the usual actions.
*
*
- * @param kind what kind of object the context menu is built on
+ * @param kind what kind of object the context menu is built on
* @param underlyingObject the object the context menu is built on
- * @param mediator the KeY mediator
+ * @param mediator the KeY mediator
* @return populated context menu
*/
public static JPopupMenu createContextMenu(ContextMenuKind kind, Object underlyingObject,
- KeYMediator mediator) {
+ KeYMediator mediator) {
JPopupMenu menu = new JPopupMenu();
if (underlyingObject instanceof Proof proof) {
for (Component comp : MainWindow.getInstance().createProofMenu(proof)
@@ -251,13 +253,13 @@ public static JPopupMenu createContextMenu(ContextMenuKind kind, Object underlyi
}
public static void addContextMenuItems(ContextMenuKind kind, JPopupMenu menu,
- Object underlyingObject, KeYMediator mediator) {
+ Object underlyingObject, KeYMediator mediator) {
getContextMenuItems(kind, underlyingObject, mediator)
.forEach(it -> sortActionIntoMenu(it, menu));
}
public static List getContextMenuItems(ContextMenuKind kind, Object underlyingObject,
- KeYMediator mediator) {
+ KeYMediator mediator) {
if (!kind.getType().isAssignableFrom(underlyingObject.getClass())) {
throw new IllegalArgumentException();
}
@@ -268,7 +270,7 @@ public static List getContextMenuItems(ContextMenuKind kind, Object unde
}
public static JMenu createTermMenu(ContextMenuKind kind, Object underlyingObject,
- KeYMediator mediator) {
+ KeYMediator mediator) {
JMenu menu = new JMenu("Extensions");
getContextMenuItems(kind, underlyingObject, mediator)
.forEach(it -> sortActionIntoMenu(it, menu));
@@ -283,7 +285,7 @@ private static void loadExtensions() {
/**
* @param clazz the interface class
- * @param the interface of the service
+ * @param the interface of the service
* @return a list of all found and enabled service implementations
*/
@SuppressWarnings("unchecked")
@@ -346,7 +348,7 @@ public static List getKeyboardShortcutsExtens
}
public static Stream getKeyboardShortcuts(KeYMediator mediator, String componentId,
- JComponent component) {
+ JComponent component) {
return getKeyboardShortcutsExtensions().stream()
.flatMap(it -> it.getShortcuts(mediator, componentId, component).stream())
.sorted(new ActionPriorityComparator());
@@ -358,7 +360,7 @@ public static Stream getKeyboardShortcuts(KeYMediator mediator, String c
* @param componentId
*/
public static void installKeyboardShortcuts(KeYMediator mediator, JComponent component,
- String componentId) {
+ String componentId) {
Stream provider = getKeyboardShortcuts(mediator, componentId, component);
provider.forEach(it -> {
int condition = it.getValue(KeyAction.SHORTCUT_FOCUSED_CONDITION) != null
@@ -388,7 +390,7 @@ public static List getTooltipExtensions() {
/**
*
* @param window the main window.
- * @param pos the position the user selected.
+ * @param pos the position the user selected.
* @return every term info string from every loaded extension.
*/
public static List getTooltipStrings(MainWindow window, PosInSequent pos) {
@@ -405,13 +407,13 @@ public static Stream getTermInfoStrings(MainWindow mainWindow, PosInSequ
}
/**
- * TODO
- * @return
+ * Helper methods that finds matches {@link Profile} and {@link OptionPanel} together.
+ * This information are provided by {@link LoadOptionPanel} interface.
*/
- public static Map createAdditionalOptionPanels() {
- List items = getExtensionInstances(KeYGuiExtension.LoadOptionPanel.class);
- HashMap map = HashMap.newHashMap(4);
- for (KeYGuiExtension.LoadOptionPanel item : items) {
+ public static Map createAdditionalOptionPanels() {
+ List items = getExtensionInstances(LoadOptionPanel.class);
+ HashMap map = HashMap.newHashMap(4);
+ for (LoadOptionPanel item : items) {
map.put(item.getProfile(), item.get());
}
return map;
diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java
index e8aa768a814..6d2fc202130 100644
--- a/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java
+++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java
@@ -9,6 +9,8 @@
import javax.swing.*;
import java.awt.*;
+/// Additional UI components for the selection of the WD semantics.
+/// @author weigl
@KeYGuiExtension.Info(experimental = false)
public class WDLoadDialogOptionPanel implements KeYGuiExtension, KeYGuiExtension.LoadOptionPanel {
@Override
@@ -49,12 +51,12 @@ public static class WDLoadDialogOptionPanelImpl implements OptionPanel {
private static final String DESCRIPTION_Y_WD_SEMANTIC = """
- Complete and along the lines of classical logic, where the
- order of terms/formulas is irrelevant. This operator is not as
- strict as the L-operator, based on strong Kleene logic. To be
- used with care, since formulas may blow up exponentially.
- Cf. "Well Defined B" by Patrick Behm, Lilian Burdy, and
- Jean-Marc Meynadier
+ Complete and along the lines of classical logic, where the
+ order of terms/formulas is irrelevant. This operator is not as
+ strict as the L-operator, based on strong Kleene logic. To be
+ used with care, since formulas may blow up exponentially.
+ Cf. "Well Defined B" by Patrick Behm, Lilian Burdy, and
+ Jean-Marc Meynadier
""";
public WDLoadDialogOptionPanelImpl() {
@@ -87,6 +89,7 @@ public void install(KeYFileChooserLoadingOptions panel) {
public void deinstall(KeYFileChooserLoadingOptions panel) {
panel.remove(lblHeader);
panel.remove(sepHeader);
+ panel.remove(lblSemantics);
panel.remove(rdbWDL);
panel.remove(rdbWDD);
panel.remove(rdbWDY);
From f63059081cd8a62d6452417d0ade1d39c6ece3e9 Mon Sep 17 00:00:00 2001
From: Alexander Weigl
Date: Sun, 15 Feb 2026 06:44:26 +0100
Subject: [PATCH 04/11] Test for taclet option
* fixed activeTacletOption in InitConfig to forbid multiple choices for the same category
* enh Info window to show current taclet options for the active proof
* refactor Info window
* enh Documentation system: Using now the doc_comments instead of XML files.
---
.../util/SymbolicExecutionSideProofUtil.java | 4 +-
key.core/src/main/antlr4/KeYParser.g4 | 27 +-
.../control/TermLabelVisibilityManager.java | 12 +-
.../ilkd/key/java/Recoder2KeYConverter.java | 2 +-
.../java/de/uka/ilkd/key/logic/DocSpace.java | 58 +++
.../de/uka/ilkd/key/logic/NamespaceSet.java | 73 ++--
.../ilkd/key/logic/label/OriginTermLabel.java | 70 ++--
.../logic/label/ParameterlessTermLabel.java | 25 +-
.../logic/label/SingletonLabelFactory.java | 6 +
.../uka/ilkd/key/logic/label/TermLabel.java | 8 +-
.../key/logic/label/TermLabelFactory.java | 5 +
.../key/logic/label/TermLabelManager.java | 7 +-
.../de/uka/ilkd/key/logic/op/TermLabelSV.java | 5 +
.../de/uka/ilkd/key/logic/sort/ArraySort.java | 2 +-
.../uka/ilkd/key/logic/sort/GenericSort.java | 9 +-
.../de/uka/ilkd/key/logic/sort/NullSort.java | 2 +-
.../ilkd/key/logic/sort/ProgramSVSort.java | 2 +-
.../de/uka/ilkd/key/logic/sort/ProxySort.java | 7 +-
.../de/uka/ilkd/key/logic/sort/SortImpl.java | 29 +-
.../nparser/builder/DeclarationBuilder.java | 74 ++--
.../key/nparser/builder/DefaultBuilder.java | 67 +++-
.../builder/FunctionPredicateBuilder.java | 11 +-
.../key/nparser/builder/TacletPBuilder.java | 13 +-
.../uka/ilkd/key/proof/init/InitConfig.java | 154 ++++----
.../key/rule/AbstractBlockContractRule.java | 14 +
.../uka/ilkd/key/rule/OneStepSimplifier.java | 25 ++
.../de/uka/ilkd/key/rule/QueryExpand.java | 12 +
.../main/java/de/uka/ilkd/key/rule/Rule.java | 8 +-
.../key/rule/UseDependencyContractRule.java | 11 +
.../key/rule/UseOperationContractRule.java | 16 +
.../uka/ilkd/key/rule/WhileInvariantRule.java | 15 +
.../de/uka/ilkd/key/speclang/SLEnvInput.java | 5 +-
.../lemma/GenericRemovingLemmaGenerator.java | 2 +-
.../taclettranslation/lemma/TacletLoader.java | 3 +-
.../lemma/UserDefinedSymbols.java | 2 +-
.../de/uka/ilkd/key/util/ExceptionTools.java | 1 +
.../de/uka/ilkd/key/util/SideProofUtil.java | 4 +-
.../de/uka/ilkd/key/proof/rules/heap.key | 72 +++-
.../uka/ilkd/key/proof/rules/javaHeader.key | 6 +
.../de/uka/ilkd/key/proof/rules/locSets.key | 43 +++
.../de/uka/ilkd/key/proof/rules/map.key | 31 +-
.../de/uka/ilkd/key/proof/rules/seq.key | 35 ++
.../de/uka/ilkd/key/proof/rules/wellfound.key | 5 +
.../org/key_project/prover/rules/RuleSet.java | 8 +-
.../java/org/key_project/logic/Choice.java | 7 +-
.../key_project/logic/HasDocumentation.java | 17 +
.../org/key_project/logic/op/Operator.java | 12 +-
.../key_project/logic/sort/AbstractSort.java | 17 -
.../java/org/key_project/logic/sort/Sort.java | 10 +-
.../java/de/uka/ilkd/key/gui/InfoTree.java | 40 --
.../de/uka/ilkd/key/gui/InfoTreeModel.java | 220 -----------
.../de/uka/ilkd/key/gui/InfoTreeNode.java | 97 -----
.../java/de/uka/ilkd/key/gui/InfoView.java | 347 ++++++++++++++----
.../uka/ilkd/key/gui/InfoViewContentPane.java | 42 ---
.../de/uka/ilkd/key/util/XMLResources.java | 66 ----
.../key/gui/help/functionExplanations.xml | 181 ---------
.../ilkd/key/gui/help/ruleExplanations.xml | 98 -----
.../key/gui/help/termLabelExplanations.xml | 27 --
.../util/collection/ImmutableSet.java | 6 +
59 files changed, 1027 insertions(+), 1150 deletions(-)
create mode 100644 key.core/src/main/java/de/uka/ilkd/key/logic/DocSpace.java
create mode 100644 key.ncore/src/main/java/org/key_project/logic/HasDocumentation.java
delete mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTree.java
delete mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeModel.java
delete mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeNode.java
delete mode 100644 key.ui/src/main/java/de/uka/ilkd/key/gui/InfoViewContentPane.java
delete mode 100644 key.ui/src/main/java/de/uka/ilkd/key/util/XMLResources.java
delete mode 100644 key.ui/src/main/resources/de/uka/ilkd/key/gui/help/functionExplanations.xml
delete mode 100644 key.ui/src/main/resources/de/uka/ilkd/key/gui/help/ruleExplanations.xml
delete mode 100644 key.ui/src/main/resources/de/uka/ilkd/key/gui/help/termLabelExplanations.xml
diff --git a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionSideProofUtil.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionSideProofUtil.java
index 82850b88104..8c9bca02e79 100644
--- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionSideProofUtil.java
+++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionSideProofUtil.java
@@ -817,9 +817,7 @@ protected ImmutableList computeTermLabelConfiguration()
? new ProofSettings(sourceInitConfig.getSettings())
: null;
initConfig.setSettings(clonedSettings);
- initConfig.setTaclet2Builder(
- (HashMap>) sourceInitConfig.getTaclet2Builder()
- .clone());
+ initConfig.setTaclet2Builder(new HashMap<>(sourceInitConfig.getTaclet2Builder()));
initConfig.setTaclets(sourceInitConfig.getTaclets());
// Create new ProofEnvironment and initialize it with values from initial one.
ProofEnvironment env = new ProofEnvironment(initConfig);
diff --git a/key.core/src/main/antlr4/KeYParser.g4 b/key.core/src/main/antlr4/KeYParser.g4
index f111efcedec..19ac344e83e 100644
--- a/key.core/src/main/antlr4/KeYParser.g4
+++ b/key.core/src/main/antlr4/KeYParser.g4
@@ -90,11 +90,11 @@ one_sort_decl
:
doc=DOC_COMMENT?
(
- GENERIC sortIds=simple_ident_dots_comma_list
+ GENERIC sortIds=simple_ident_dots_comma_list_with_docs
(ONEOF sortOneOf = oneof_sorts)?
(EXTENDS sortExt = extends_sorts)? SEMI
- | PROXY sortIds=simple_ident_dots_comma_list (EXTENDS sortExt=extends_sorts)? SEMI
- | ABSTRACT? sortIds=simple_ident_dots_comma_list (EXTENDS sortExt=extends_sorts)? SEMI
+ | PROXY sortIds=simple_ident_dots_comma_list_with_docs (EXTENDS sortExt=extends_sorts)? SEMI
+ | ABSTRACT? sortIds=simple_ident_dots_comma_list_with_docs (EXTENDS sortExt=extends_sorts)? SEMI
)
;
@@ -108,6 +108,13 @@ simple_ident_dots_comma_list
simple_ident_dots (COMMA simple_ident_dots)*
;
+simple_ident_dots_comma_list_with_docs
+:
+ simple_ident_dots_with_docs (COMMA simple_ident_dots_with_docs)*
+;
+
+simple_ident_dots_with_docs: DOC_COMMENT? simple_ident_dots;
+
extends_sorts
:
@@ -132,7 +139,7 @@ prog_var_decls
LBRACE
(
kjt = keyjavatype
- var_names = simple_ident_comma_list
+ var_names = simple_ident_comma_list_with_docs
SEMI
)*
RBRACE
@@ -154,6 +161,10 @@ simple_ident_comma_list
id = simple_ident (COMMA id = simple_ident )*
;
+simple_ident_comma_list_with_docs
+:
+ id+=simple_ident_with_doc (COMMA id+=simple_ident_with_doc)*
+;
schema_var_decls :
SCHEMAVARIABLES LBRACE
@@ -250,6 +261,7 @@ datatype_decl:
;
datatype_constructor:
+ doc=DOC_COMMENT?
name=simple_ident
(
LPAREN
@@ -321,7 +333,12 @@ where_to_bind:
ruleset_decls
:
- HEURISTICSDECL LBRACE (doc+=DOC_COMMENT? id+=simple_ident SEMI)* RBRACE
+ HEURISTICSDECL LBRACE (id+=simple_ident_with_doc SEMI)* RBRACE
+;
+
+simple_ident_with_doc
+:
+ doc=DOC_COMMENT? id=simple_ident
;
sortId
diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/TermLabelVisibilityManager.java b/key.core/src/main/java/de/uka/ilkd/key/control/TermLabelVisibilityManager.java
index 4e04c3bec13..03971265fb7 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/control/TermLabelVisibilityManager.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/control/TermLabelVisibilityManager.java
@@ -26,7 +26,7 @@ public class TermLabelVisibilityManager implements VisibleTermLabels {
/**
* The names of all term labels that should never be printed.
*/
- private static final Name[] ALWAYS_HIDDEN = { OriginTermLabel.NAME };
+ private static final Name[] ALWAYS_HIDDEN = {OriginTermLabel.NAME};
/**
* A switch to choose whether labels are to be shown or not.
@@ -43,7 +43,7 @@ public class TermLabelVisibilityManager implements VisibleTermLabels {
* All available {@link TermLabelVisibilityManagerListener}s.
*/
private final List listeners =
- new LinkedList<>();
+ new LinkedList<>();
/**
* Constructs a new TermLabelVisibilityManager.
@@ -90,7 +90,7 @@ public boolean isHidden(Name labelName) {
* Sets the state of the term label with the passed name to hidden or not.
*
* @param labelName The name of a term label
- * @param hidden The boolean value whether the term label should be hidden or not
+ * @param hidden The boolean value whether the term label should be hidden or not
*/
public void setHidden(Name labelName, boolean hidden) {
if (hidden) {
@@ -157,7 +157,7 @@ public TermLabelVisibilityManagerListener[] getTermLabelVisibilityManagerListene
/**
* Fires the event
- * {@link TermLabelVisibilityManagerListener#visibleLabelsChanged( TermLabelVisibilityManagerEvent)}
+ * {@link TermLabelVisibilityManagerListener#visibleLabelsChanged(TermLabelVisibilityManagerEvent)}
* to all listeners.
*
* @param e The event object.
@@ -200,8 +200,8 @@ public static List getSortedTermLabelNames(TermLabelManager manager) {
List labelNames = manager.getSupportedTermLabelNames().toList();
labelNames.sort(
- (t, t1) -> String.CASE_INSENSITIVE_ORDER.compare(t.toString(), t1.toString()));
+ (t, t1) -> String.CASE_INSENSITIVE_ORDER.compare(t.toString(), t1.toString()));
return labelNames;
}
-}
+}
\ No newline at end of file
diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/Recoder2KeYConverter.java b/key.core/src/main/java/de/uka/ilkd/key/java/Recoder2KeYConverter.java
index 02cb218f130..092d72380cf 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/java/Recoder2KeYConverter.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/java/Recoder2KeYConverter.java
@@ -762,7 +762,7 @@ public DLEmbeddedExpression convert(EscapeExpression e) {
sortName, e.getStartPosition()));
}
- var doc = sort.getDocumentation();
+ var doc = namespaceSet.docs().find(sort);
if (doc == null) {
throw new ConvertException(
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/DocSpace.java b/key.core/src/main/java/de/uka/ilkd/key/logic/DocSpace.java
new file mode 100644
index 00000000000..5799afeebf1
--- /dev/null
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/DocSpace.java
@@ -0,0 +1,58 @@
+package de.uka.ilkd.key.logic;
+
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+import org.key_project.logic.HasDocumentation;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+@NullMarked
+public class DocSpace {
+ private @Nullable DocSpace parent;
+ private final Map documentation = new TreeMap<>();
+
+ public DocSpace() {}
+
+ public DocSpace(Map documentation) {
+ this.documentation.putAll(documentation);
+ }
+
+ public DocSpace(DocSpace parent) {
+ this.parent = parent;
+ }
+
+ public @Nullable String find(String key) {
+ var value = documentation.get(key);
+ if (value != null) return value;
+ if (parent != null) return parent.find(key);
+ return null;
+ }
+
+ public @Nullable String find(HasDocumentation entity) {
+ var doc = entity.getDocumentation();
+ if(doc != null) {
+ return doc;
+ }
+ return find(entity.getDocumentationKey());
+ }
+
+ public void add(DocSpace space) {
+ this.documentation.putAll(space.documentation);
+ }
+
+ public @Nullable DocSpace parent() {
+ return parent;
+ }
+
+ public void describe(HasDocumentation entity, @Nullable String doc) {
+ if (doc == null) {
+ return;
+ }
+ documentation.put(entity.getDocumentationKey(), doc);
+ }
+
+ public DocSpace copy() {
+ return new DocSpace(documentation);
+ }
+}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java b/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java
index e87be8f8072..f8d7afe9171 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java
@@ -5,7 +5,7 @@
import de.uka.ilkd.key.logic.op.IProgramVariable;
-
+import org.jspecify.annotations.NullMarked;
import org.key_project.logic.Choice;
import org.key_project.logic.Name;
import org.key_project.logic.Named;
@@ -15,44 +15,54 @@
import org.key_project.logic.sort.Sort;
import org.key_project.prover.rules.RuleSet;
-import org.jspecify.annotations.NonNull;
-
+@NullMarked
public class NamespaceSet {
- private Namespace<@NonNull QuantifiableVariable> varNS = new Namespace<>();
- private Namespace<@NonNull IProgramVariable> progVarNS = new Namespace<>();
+ private Namespace varNS = new Namespace<>();
+ private Namespace progVarNS = new Namespace<>();
// TODO: Operators should not be local to goals
- private Namespace<@NonNull Function> funcNS = new Namespace<>();
- private Namespace<@NonNull RuleSet> ruleSetNS = new Namespace<>();
- private Namespace<@NonNull Sort> sortNS = new Namespace<>();
- private Namespace<@NonNull Choice> choiceNS = new Namespace<>();
+ private Namespace funcNS = new Namespace<>();
+ private Namespace ruleSetNS = new Namespace<>();
+ private Namespace sortNS = new Namespace<>();
+ private Namespace choiceNS = new Namespace<>();
+ private final DocSpace documentation = new DocSpace();
public NamespaceSet() {
}
- public NamespaceSet(Namespace<@NonNull QuantifiableVariable> varNS,
- Namespace<@NonNull Function> funcNS,
- Namespace<@NonNull Sort> sortNS, Namespace<@NonNull RuleSet> ruleSetNS,
- Namespace<@NonNull Choice> choiceNS,
- Namespace<@NonNull IProgramVariable> programVarNS) {
+ public NamespaceSet(Namespace varNS,
+ Namespace funcNS,
+ Namespace sortNS, Namespace ruleSetNS,
+ Namespace choiceNS,
+ Namespace programVarNS) {
+ this(varNS, funcNS, sortNS, ruleSetNS, choiceNS, programVarNS, new DocSpace());
+ }
+
+ public NamespaceSet(Namespace varNS,
+ Namespace funcNS,
+ Namespace sortNS, Namespace ruleSetNS,
+ Namespace choiceNS,
+ Namespace programVarNS,
+ DocSpace documentation) {
this.varNS = varNS;
this.progVarNS = programVarNS;
this.funcNS = funcNS;
this.sortNS = sortNS;
this.ruleSetNS = ruleSetNS;
this.choiceNS = choiceNS;
+ this.documentation.add(documentation);
}
public NamespaceSet copy() {
return new NamespaceSet(variables().copy(), functions().copy(),
sorts().copy(),
- ruleSets().copy(), choices().copy(), programVariables().copy());
+ ruleSets().copy(), choices().copy(), programVariables().copy(),
+ documentation.copy());
}
public NamespaceSet shallowCopy() {
return new NamespaceSet(variables(), functions(), sorts(), ruleSets(),
- choices(),
- programVariables());
+ choices(), programVariables(), new DocSpace(documentation));
}
// TODO MU: Rename into sth with wrap or similar
@@ -63,51 +73,51 @@ public NamespaceSet copyWithParent() {
new Namespace<>(programVariables()));
}
- public Namespace<@NonNull QuantifiableVariable> variables() {
+ public Namespace variables() {
return varNS;
}
- public void setVariables(Namespace<@NonNull QuantifiableVariable> varNS) {
+ public void setVariables(Namespace varNS) {
this.varNS = varNS;
}
- public Namespace<@NonNull IProgramVariable> programVariables() {
+ public Namespace programVariables() {
return progVarNS;
}
- public void setProgramVariables(Namespace<@NonNull IProgramVariable> progVarNS) {
+ public void setProgramVariables(Namespace progVarNS) {
this.progVarNS = progVarNS;
}
- public Namespace<@NonNull Function> functions() {
+ public Namespace functions() {
return funcNS;
}
- public void setFunctions(Namespace<@NonNull Function> funcNS) {
+ public void setFunctions(Namespace funcNS) {
this.funcNS = funcNS;
}
- public Namespace<@NonNull RuleSet> ruleSets() {
+ public Namespace ruleSets() {
return ruleSetNS;
}
- public void setRuleSets(Namespace<@NonNull RuleSet> ruleSetNS) {
+ public void setRuleSets(Namespace ruleSetNS) {
this.ruleSetNS = ruleSetNS;
}
- public Namespace<@NonNull Sort> sorts() {
+ public Namespace sorts() {
return sortNS;
}
- public void setSorts(Namespace<@NonNull Sort> sortNS) {
+ public void setSorts(Namespace sortNS) {
this.sortNS = sortNS;
}
- public Namespace<@NonNull Choice> choices() {
+ public Namespace choices() {
return choiceNS;
}
- public void setChoices(Namespace<@NonNull Choice> choiceNS) {
+ public void setChoices(Namespace choiceNS) {
this.choiceNS = choiceNS;
}
@@ -227,7 +237,10 @@ public void flushToParent() {
public NamespaceSet getParent() {
return new NamespaceSet(varNS.parent(), funcNS.parent(), sortNS.parent(),
- ruleSetNS.parent(), choiceNS.parent(), progVarNS.parent());
+ ruleSetNS.parent(), choiceNS.parent(), progVarNS.parent(), documentation.parent());
}
+ public DocSpace docs() {
+ return documentation;
+ }
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java
index 05bea742469..1706dc29b23 100755
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java
@@ -59,12 +59,12 @@ public class OriginTermLabel implements TermLabel {
/**
* Display name for {@link OriginTermLabel}s.
*/
- public final static Name NAME = new Name("origin");
+ public static final Name NAME = new Name("origin");
/**
* @see #getTLChildCount()
*/
- public final static int CHILD_COUNT = 2;
+ public static final int CHILD_COUNT = 2;
public static final Sort[] EMPTY_SORTS = new Sort[0];
@@ -143,7 +143,7 @@ public static Origin getOrigin(PosInOccurrence pio) {
/**
* Creates a new {@link OriginTermLabel}.
*
- * @param origin the term's origin.
+ * @param origin the term's origin.
* @param subtermOrigins the origins of the term's (former) subterms.
*/
OriginTermLabel(Origin origin, Set subtermOrigins) {
@@ -195,7 +195,7 @@ public boolean equals(Object obj) {
* various problems during proof search.
*
*
- * @param term a term
+ * @param term a term
* @param services services.
* @return {@code true} iff an {@code OriginTermLabel} can be added to the specified term.
*/
@@ -214,10 +214,10 @@ public static boolean canAddLabel(JTerm term, Services services) {
* various problems during proof search.
*
*
- * @param op the specified operator.
+ * @param op the specified operator.
* @param services services.
* @return {@code true} iff an {@code OriginTermLabel} can be added to a term with the specified
- * operator.
+ * operator.
*/
public static boolean canAddLabel(Operator op, Services services) {
// TODO: Instead of not adding origin labels to certain terms, we should investigate why
@@ -248,7 +248,7 @@ public static boolean canAddLabel(Operator op, Services services) {
/**
* Removes all {@link OriginTermLabel} from the specified sequent.
*
- * @param seq the sequent to transform.
+ * @param seq the sequent to transform.
* @param services services.
* @return the resulting sequent change info.
*/
@@ -260,11 +260,11 @@ public static SequentChangeInfo removeOriginLabels(
for (int i = 1; i <= seq.size(); ++i) {
SequentFormula oldFormula = seq.getFormulaByNr(i);
SequentFormula newFormula = new SequentFormula(
- removeOriginLabels((JTerm) oldFormula.formula(), services));
+ removeOriginLabels((JTerm) oldFormula.formula(), services));
SequentChangeInfo change =
- seq.changeFormula(newFormula,
- PosInOccurrence.findInSequent(seq, i,
- PosInTerm.getTopLevel()));
+ seq.changeFormula(newFormula,
+ PosInOccurrence.findInSequent(seq, i,
+ PosInTerm.getTopLevel()));
if (changes == null) {
changes = change;
@@ -279,7 +279,7 @@ public static SequentChangeInfo removeOriginLabels(
/**
* Removes all {@link OriginTermLabel} from the specified term and its sub-terms.
*
- * @param term the term to transform.
+ * @param term the term to transform.
* @param services services.
* @return the transformed term.
*/
@@ -303,7 +303,7 @@ public static JTerm removeOriginLabels(JTerm term, Services services) {
}
return tf.createTerm(term.op(), newSubs, term.boundVars(),
- new ImmutableArray<>(labels));
+ new ImmutableArray<>(labels));
}
/**
@@ -431,7 +431,7 @@ public static Origin computeCommonOrigin(final Set extends Origin> origins) {
* This method transforms a term in such a way that every {@link OriginTermLabel} contains all
* the correct {@link #getSubtermOrigins()}.
*
- * @param term the term to transform.
+ * @param term the term to transform.
* @param services services.
* @return the transformed term.
*/
@@ -442,10 +442,10 @@ public static JTerm collectSubtermOrigins(JTerm term, Services services) {
SubTermOriginData newSubs = getSubTermOriginData(term.subs(), services);
final ImmutableArray labels =
- computeOriginLabelsFromSubTermOrigins(term, newSubs.origins);
+ computeOriginLabelsFromSubTermOrigins(term, newSubs.origins);
return services.getTermFactory().createTerm(term.op(), newSubs.terms, term.boundVars(),
- labels);
+ labels);
}
@Override
@@ -506,7 +506,7 @@ public Set getSubtermOrigins() {
private static ImmutableArray computeOriginLabelsFromSubTermOrigins(final JTerm term,
- final Set origins) {
+ final Set origins) {
List labels = term.getLabels().toList();
final OriginTermLabel oldLabel = (OriginTermLabel) term.getLabel(NAME);
@@ -518,7 +518,7 @@ private static ImmutableArray computeOriginLabelsFromSubTermOrigins(f
}
} else if (!origins.isEmpty()) {
final OriginTermLabel newLabel =
- new OriginTermLabel(computeCommonOrigin(origins), origins);
+ new OriginTermLabel(computeCommonOrigin(origins), origins);
labels.add(newLabel);
}
@@ -526,14 +526,14 @@ private static ImmutableArray computeOriginLabelsFromSubTermOrigins(f
}
/**
- * @param subs the sub-terms to be searched
+ * @param subs the sub-terms to be searched
* @param services a services object used for getting type information and creating the new
- * sub-term
+ * sub-term
* @return origin information about the searched sub-terms stored in a {@link SubTermOriginData}
- * object.
+ * object.
*/
private static SubTermOriginData getSubTermOriginData(final ImmutableArray subs,
- final Services services) {
+ final Services services) {
JTerm[] newSubs = new JTerm[subs.size()];
Set origins = new LinkedHashSet<>();
@@ -559,15 +559,19 @@ private static SubTermOriginData getSubTermOriginData(final ImmutableArray origins;
/**
* This method constructs an object of type {@link SubTermOriginData}.
*
- * @param subterms the collected sub-terms
+ * @param subterms the collected sub-terms
* @param subtermOrigins the origin information collected from these sub-terms
*/
public SubTermOriginData(JTerm[] subterms, Set subtermOrigins) {
@@ -643,7 +647,7 @@ public static final class NodeOrigin extends Origin {
*
* @param specType the spec type the term originates from.
* @param ruleName the name of the rule applied at the node the term originates from.
- * @param nodeNr the {@link Node#serialNr()} of the node the term originates from.
+ * @param nodeNr the {@link Node#serialNr()} of the node the term originates from.
*/
public NodeOrigin(SpecType specType, String ruleName, int nodeNr) {
super(specType);
@@ -713,7 +717,7 @@ public static final class FileOrigin extends Origin {
*
* @param specType the spec type the term originates from.
* @param fileName the file the term originates from.
- * @param line the line in the file.
+ * @param line the line in the file.
*/
public FileOrigin(SpecType specType, @Nullable URI fileName, int line) {
super(specType);
@@ -775,6 +779,18 @@ public boolean equals(Object obj) {
}
}
+ @Override
+ public @Nullable String getDocumentation() {
+ return """
+ This label saves a term's origin in the JML specification as well as the origins of all of its subterms and former subterms.
+
+ For example, if the file "Example.java" contains the clause "requires R" at line 20, then every JavaDL term that is generated from R will have the origin
+ "requires @ Example.java @ line 20".
+
+ Origin labels are not printed in the sequent view. To see a term's origin, you can mouse over it while holding the ALT button. If you want more detailed information, left click on the term and then on "Show Origin".
+ """;
+ }
+
/**
* A {@code SpecType} is any type of JML specification which gets translated into JavaDL.
*
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java
index 596410ce3e8..19965f5014b 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java
@@ -5,6 +5,7 @@
import de.uka.ilkd.key.rule.LoopScopeInvariantRule;
+import org.jspecify.annotations.Nullable;
import org.key_project.logic.Name;
/**
@@ -56,12 +57,22 @@ public final class ParameterlessTermLabel implements TermLabel {
*/
public static final Name SHORTCUT_EVALUATION_LABEL_NAME = new Name("SC");
+ public static final String SHORTCUT_EVALUATION_LABEL_DOC =
+ """
+ The term label SC is used to indicate that a logical operator has originally been "shortcut" operator.
+
+ For instance, both conjunction operators in JML (i.e., && and &) are translated to the same function in JavaDL. To differentiate between the two, the translation of && adds the label SC.
+
+ This is relevant for welldefinedness checks.
+ """;
+
/**
* Label attached to a term with the logical operator '{@literal ||}' or '{@literal &&}' to
* distinguish from '{@literal |}' or '{@literal &}' respectively.
*/
public static final TermLabel SHORTCUT_EVALUATION_LABEL =
- new ParameterlessTermLabel(SHORTCUT_EVALUATION_LABEL_NAME);
+ new ParameterlessTermLabel(SHORTCUT_EVALUATION_LABEL_NAME,
+ SHORTCUT_EVALUATION_LABEL_DOC);
/**
* Name of {@link #UNDEFINED_VALUE_LABEL}.
@@ -115,6 +126,8 @@ public final class ParameterlessTermLabel implements TermLabel {
*/
private final Name name;
+ private final @Nullable String documentation;
+
/**
* Instantiates a new simple term label.
*
@@ -122,8 +135,13 @@ public final class ParameterlessTermLabel implements TermLabel {
* null.
*/
public ParameterlessTermLabel(Name name) {
+ this(name, null);
+ }
+
+ public ParameterlessTermLabel(Name name, @Nullable String doc) {
assert name != null;
this.name = name;
+ this.documentation = doc;
}
@Override
@@ -181,4 +199,9 @@ public boolean equals(Object obj) {
public int hashCode() {
return name.hashCode();
}
+
+ @Override
+ public @Nullable String getDocumentation() {
+ return documentation;
+ }
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java
index 025d5cf4208..ee5118963b9 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java
@@ -6,6 +6,7 @@
import java.util.List;
import de.uka.ilkd.key.logic.TermServices;
+import org.jspecify.annotations.Nullable;
/**
* A factory for creating singleton {@link TermLabel}.
@@ -33,6 +34,11 @@ public SingletonLabelFactory(T singletonLabel) {
this.singletonLabel = singletonLabel;
}
+ @Override
+ public @Nullable String getDocumentation() {
+ return singletonLabel.getDocumentation();
+ }
+
/**
* {@inheritDoc}
*
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java
index 389a84ab4f0..435725615c6 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java
@@ -16,6 +16,7 @@
import de.uka.ilkd.key.rule.label.TermLabelRefactoring.RefactoringScope;
import de.uka.ilkd.key.rule.label.TermLabelUpdate;
+import org.key_project.logic.HasDocumentation;
import org.key_project.logic.Name;
import org.key_project.logic.Named;
import org.key_project.logic.TerminalSyntaxElement;
@@ -151,7 +152,7 @@
* @see TermLabelManager
*/
// spotless:on
-public interface TermLabel extends Named, /* TODO: Remove */ TerminalSyntaxElement {
+public interface TermLabel extends Named, HasDocumentation, /* TODO: Remove */ TerminalSyntaxElement {
/**
* Retrieves the i-th parameter object of this term label.
@@ -183,4 +184,9 @@ public interface TermLabel extends Named, /* TODO: Remove */ TerminalSyntaxEleme
default boolean isProofRelevant() {
return true;
}
+
+ @Override
+ default String getDocumentationKey() {
+ return "termlabel/" + name();
+ }
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java
index a8fd1cecafe..98db9a19498 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java
@@ -6,6 +6,7 @@
import java.util.List;
import de.uka.ilkd.key.logic.TermServices;
+import org.jspecify.annotations.Nullable;
/**
* A factory for creating TermLabel objects.
@@ -45,4 +46,8 @@ public interface TermLabelFactory {
* @throws TermLabelException if the parameters were illegally formatted
*/
T parseInstance(List arguments, TermServices services) throws TermLabelException;
+
+ default @Nullable String getDocumentation() {
+ return null;
+ }
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java
index f08bb194f98..a9438317abb 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java
@@ -71,8 +71,7 @@ public class TermLabelManager {
/**
* {@link Map}s the {@link Name} of a {@link TermLabel} to its {@link TermLabelFactory}.
*/
- private final Map> factoryMap =
- new LinkedHashMap<>();
+ private final Map> factoryMap = new LinkedHashMap<>();
/**
* {@link Map}s the {@link Name} of a {@link TermLabel} to its {@link TermLabelPolicy} applied
@@ -1493,6 +1492,10 @@ protected RefactoringsContainer computeRefactorings(TermLabelState state, Servic
return refactorings;
}
+ public Map> getFactories() {
+ return Collections.unmodifiableMap(factoryMap);
+ }
+
/**
* Utility class used by
* {@link TermLabelManager#computeRefactorings(TermLabelState, Services, PosInOccurrence, JTerm, Rule, Goal, Object, JTerm)}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java b/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java
index ca2f315c10d..c892c952df9 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java
@@ -31,4 +31,9 @@ public int getTLChildCount() {
public Object getTLChild(int i) {
throw new IndexOutOfBoundsException();
}
+
+ @Override
+ public String getDocumentationKey() {
+ return super.getDocumentationKey();
+ }
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java
index 22fcd5e166c..d481e0ebe3b 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java
@@ -42,7 +42,7 @@ public final class ArraySort extends SortImpl {
private ArraySort(ImmutableSet extendsSorts, SortKey sk) {
super(new Name((sk.elemType != null ? sk.elemType.getName() : sk.elemSort.name()) + "[]"),
- extendsSorts, false, "", "");
+ extendsSorts, false, "");
if (extendsSorts.isEmpty()) {
throw new IllegalArgumentException("An ArraySort extends typically three sorts"
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java
index f714f27c47d..6a2be3f9291 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java
@@ -46,22 +46,21 @@ public final class GenericSort extends SortImpl {
* @param ext supersorts of this sort, which have to be either concrete sorts or plain generic
* sorts (i.e. not collection sorts of generic sorts)
*/
- public GenericSort(Name name, ImmutableSet ext, ImmutableSet oneOf,
- String documentation, String origin)
+ public GenericSort(Name name, ImmutableSet ext, ImmutableSet oneOf, String origin)
throws GenericSupersortException {
- super(name, ext, false, documentation, origin);
+ super(name, ext, false, origin);
this.oneOf = oneOf;
checkSupersorts();
}
public GenericSort(Name name, ImmutableSet ext, ImmutableSet oneOf)
throws GenericSupersortException {
- this(name, ext, oneOf, "", "");
+ this(name, ext, oneOf, "");
}
public GenericSort(Name name) {
- super(name, DefaultImmutableSet.nil(), false, "", "");
+ super(name, DefaultImmutableSet.nil(), false, "");
this.oneOf = DefaultImmutableSet.nil();
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java
index c181b22e9c7..cf68e666b45 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java
@@ -35,7 +35,7 @@ public final class NullSort extends SortImpl {
public NullSort(Sort objectSort) {
- super(NAME, null, false, "", "");
+ super(NAME, null, false, "");
assert objectSort != null;
this.objectSort = objectSort;
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java
index c56513e2fb4..8182bb15eef 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java
@@ -279,7 +279,7 @@ public boolean canStandFor(ProgramElement pe, Services services) {
// --------------------------------------------------------------------------
protected ProgramSVSort(Name name) {
- super(name, DefaultImmutableSet.nil(), false, "", "");
+ super(name, DefaultImmutableSet.nil(), false, "");
NAME2SORT.put(name, this);
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java
index fca9856c8a9..c6954a6ed35 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java
@@ -9,12 +9,11 @@
import org.key_project.util.collection.ImmutableSet;
public class ProxySort extends SortImpl {
-
- public ProxySort(Name name, ImmutableSet ext, String documentation, String origin) {
- super(name, ext, false, documentation, origin);
+ public ProxySort(Name name, ImmutableSet ext, String origin) {
+ super(name, ext, false, origin);
}
public ProxySort(Name name) {
- this(name, DefaultImmutableSet.nil(), "", "");
+ this(name, DefaultImmutableSet.nil(), "");
}
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java
index 40f5a1bba5b..d3c319766a6 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java
@@ -17,44 +17,36 @@
* Abstract base class for implementations of the Sort interface.
*/
public class SortImpl extends AbstractSort {
- /**
- * Documentation for this sort given by the associated documentation comment.
- *
- * @see de.uka.ilkd.key.nparser.KeYParser.One_sort_declContext#doc
- */
- private final String documentation;
-
/** Information of the origin of this sort */
private final String origin;
+
private ImmutableSet ext;
- public SortImpl(Name name, ImmutableSet ext, boolean isAbstract, String documentation,
- String origin) {
+ public SortImpl(Name name, ImmutableSet ext, boolean isAbstract, String origin) {
super(name, isAbstract);
this.ext = ext;
- this.documentation = documentation;
this.origin = origin;
}
- public SortImpl(Name name, ImmutableSet ext, String documentation, String origin) {
- this(name, ext, false, documentation, origin);
+ public SortImpl(Name name, ImmutableSet ext, String origin) {
+ this(name, ext, false, origin);
}
public SortImpl(Name name, ImmutableSet ext, boolean isAbstract) {
- this(name, ext, isAbstract, "", "");
+ this(name, ext, isAbstract, "");
}
public SortImpl(Name name, ImmutableSet ext) {
- this(name, ext, false, "", "");
+ this(name, ext, false, "");
}
public SortImpl(Name name, Sort ext) {
- this(name, DefaultImmutableSet.nil().add(ext), false, "", "");
+ this(name, DefaultImmutableSet.nil().add(ext), false, "");
}
public SortImpl(Name name) {
- this(name, DefaultImmutableSet.nil(), "", "");
+ this(name, DefaultImmutableSet.nil(), "");
}
@Override
@@ -88,11 +80,6 @@ public String declarationString() {
return name().toString();
}
- @Override
- public @Nullable String getDocumentation() {
- return documentation;
- }
-
@Override
public @Nullable String getOrigin() {
return origin;
diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java
index 30d94ea933c..495bdb250ce 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java
@@ -3,10 +3,9 @@
* SPDX-License-Identifier: GPL-2.0-only */
package de.uka.ilkd.key.nparser.builder;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import de.uka.ilkd.key.java.Services;
import de.uka.ilkd.key.java.abstraction.KeYJavaType;
@@ -18,7 +17,9 @@
import de.uka.ilkd.key.nparser.KeYParser;
import de.uka.ilkd.key.nparser.ParsingFacade;
+import org.antlr.v4.runtime.tree.TerminalNode;
import org.key_project.logic.Choice;
+import org.key_project.logic.HasDocumentation;
import org.key_project.logic.Name;
import org.key_project.logic.Named;
import org.key_project.logic.sort.Sort;
@@ -57,34 +58,33 @@ public DeclarationBuilder(Services services, NamespaceSet nss) {
@Override
public Object visitDecls(KeYParser.DeclsContext ctx) {
mapMapOf(ctx.option_decls(), ctx.options_choice(), ctx.ruleset_decls(), ctx.sort_decls(),
- ctx.datatype_decls(),
- ctx.prog_var_decls(), ctx.schema_var_decls());
+ ctx.datatype_decls(),
+ ctx.prog_var_decls(), ctx.schema_var_decls());
return null;
}
@Override
public Object visitDatatype_decl(KeYParser.Datatype_declContext ctx) {
- // boolean freeAdt = ctx.FREE() != null;
var name = ctx.name.getText();
- var doc = ctx.DOC_COMMENT() != null
- ? ctx.DOC_COMMENT().getText()
- : null;
+ var doc = processDocumentation(ctx.doc);
var origin = BuilderHelpers.getPosition(ctx);
- var s = new SortImpl(new Name(name), ImmutableSet.empty(), false, doc, origin);
+ var s = new SortImpl(new Name(name), ImmutableSet.empty(), false, origin);
sorts().addSafely(s);
+ docsSpace().describe(s, doc);
return null;
}
@Override
public Object visitProg_var_decls(KeYParser.Prog_var_declsContext ctx) {
- for (int i = 0; i < ctx.simple_ident_comma_list().size(); i++) {
- List varNames = accept(ctx.simple_ident_comma_list(i));
+ for (int i = 0; i < ctx.simple_ident_comma_list_with_docs().size(); i++) {
+ var c = ctx.simple_ident_comma_list_with_docs(i);
+ List varNames = c.simple_ident_with_doc()
+ .stream().map(it -> (String) accept(it.simple_ident())).toList();
KeYJavaType kjt = accept(ctx.keyjavatype(i));
assert varNames != null;
for (String varName : varNames) {
if (varName.equals("null")) {
- semanticError(ctx.simple_ident_comma_list(i),
- "Function '" + varName + "' is already defined!");
+ semanticError(c, "Function '" + varName + "' is already defined!");
}
ProgramElementName pvName = new ProgramElementName(varName);
Named name = lookup(pvName);
@@ -92,8 +92,7 @@ public Object visitProg_var_decls(KeYParser.Prog_var_declsContext ctx) {
// commented out as pv do not have unique name (at the moment)
// throw new AmbigiousDeclException(varName, getSourceName(), getLine(),
// getColumn())
- if (!(name instanceof ProgramVariable)
- || !((ProgramVariable) name).getKeYJavaType().equals(kjt)) {
+ if (!(name instanceof ProgramVariable pv) || !(pv.getKeYJavaType().equals(kjt))) {
programVariables().add(new LocationVariable(pvName, kjt));
}
} else {
@@ -108,21 +107,30 @@ public Object visitProg_var_decls(KeYParser.Prog_var_declsContext ctx) {
@Override
public Object visitChoice(KeYParser.ChoiceContext ctx) {
String cat = ctx.category.getText();
+ String catDoc = processDocumentation(ctx.maindoc);
+ docsSpace().describe(new HasDocumentation.OptionCategory(cat), catDoc);
+
for (KeYParser.OptionDeclContext optdecl : ctx.optionDecl()) {
Token catctx = optdecl.IDENT;
String name = cat + ":" + catctx.getText();
+
Choice c = choices().lookup(new Name(name));
if (c == null) {
c = new Choice(catctx.getText(), cat);
choices().add(c);
+
+ var doc = processDocumentation(optdecl.DOC_COMMENT);
+ docsSpace().describe(c, doc);
}
category2Default.putIfAbsent(cat, name);
}
+
category2Default.computeIfAbsent(cat, it -> {
- choices().add(new Choice("On", cat));
- choices().add(new Choice("Off", cat));
+ choices().add(new Choice(cat + ":On", cat));
+ choices().add(new Choice(cat + ":Off", cat));
return cat + ":On";
});
+
return null;
}
@@ -142,9 +150,9 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) {
boolean isProxySort = ctx.PROXY() != null;
boolean isAbstractSort = ctx.ABSTRACT() != null;
List createdSorts = new LinkedList<>();
- var documentation = ParsingFacade.getValueDocumentation(ctx.DOC_COMMENT());
- for (var idCtx : ctx.sortIds.simple_ident_dots()) {
- String sortId = accept(idCtx);
+ var sectionDoc = processDocumentation(ctx.DOC_COMMENT());
+ for (var idCtx : ctx.sortIds.simple_ident_dots_with_docs()) {
+ String sortId = accept(idCtx.simple_ident_dots());
Name sortName = new Name(sortId);
ImmutableSet ext = sortExt == null ? ImmutableSet.empty()
@@ -158,8 +166,7 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) {
Sort s = null;
if (isGenericSort) {
try {
- var gs = new GenericSort(sortName, ext, oneOf, documentation,
- BuilderHelpers.getPosition(idCtx));
+ var gs = new GenericSort(sortName, ext, oneOf, BuilderHelpers.getPosition(idCtx));
s = gs;
} catch (GenericSupersortException e) {
semanticError(ctx, "Illegal sort given");
@@ -168,16 +175,17 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) {
s = JavaDLTheory.ANY;
} else {
if (isProxySort) {
- var ps = new ProxySort(sortName, ext, documentation,
- BuilderHelpers.getPosition(idCtx));
+ var ps = new ProxySort(sortName, ext, BuilderHelpers.getPosition(idCtx));
s = ps;
} else {
- var si = new SortImpl(sortName, ext, isAbstractSort,
- documentation, BuilderHelpers.getPosition(idCtx));
+ var si = new SortImpl(sortName, ext, isAbstractSort, BuilderHelpers.getPosition(idCtx));
s = si;
}
}
assert s != null;
+ String doc = processDocumentation(idCtx.DOC_COMMENT());
+ docsSpace().describe(s,
+ Stream.of(doc, sectionDoc).filter(Objects::nonNull).collect(Collectors.joining("\n")));
sorts().add(s);
createdSorts.add(s);
} else {
@@ -185,8 +193,8 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) {
// local namespaces for generic sorts
// addWarning(ctx, "Sort declaration is ignored, due to collision.");
LOGGER.debug("Sort declaration of {} in {} is ignored due to collision (already "
- + "present in {}).", sortName, BuilderHelpers.getPosition(ctx),
- existingSort.getOrigin());
+ + "present in {}).", sortName, BuilderHelpers.getPosition(ctx),
+ existingSort.getOrigin());
}
}
return createdSorts;
@@ -210,10 +218,13 @@ public List visitOneof_sorts(KeYParser.Oneof_sortsContext ctx) {
@Override
public Object visitRuleset_decls(KeYParser.Ruleset_declsContext ctx) {
- for (String id : this.mapOf(ctx.simple_ident())) {
+ for (KeYParser.Simple_ident_with_docContext iddoc : ctx.simple_ident_with_doc()) {
+ String id = accept(iddoc.simple_ident());
+ String doc = processDocumentation(iddoc.DOC_COMMENT());
RuleSet h = new RuleSet(new Name(id));
if (ruleSets().lookup(new Name(id)) == null) {
ruleSets().add(h);
+ docsSpace().describe(h, doc);
}
}
return null;
@@ -225,5 +236,4 @@ public Object visitOptions_choice(KeYParser.Options_choiceContext ctx) {
return null;
}
-
}
diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java
index 059f24f1696..683e03144a5 100644
--- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java
+++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java
@@ -7,6 +7,8 @@
import java.util.Collection;
import java.util.List;
import java.util.ResourceBundle;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import de.uka.ilkd.key.java.JavaInfo;
import de.uka.ilkd.key.java.Services;
@@ -22,6 +24,8 @@
import de.uka.ilkd.key.logic.sort.NullSort;
import de.uka.ilkd.key.nparser.KeYParser;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
import org.key_project.logic.*;
import org.key_project.logic.op.Function;
import org.key_project.logic.op.Operator;
@@ -47,7 +51,7 @@ public class DefaultBuilder extends AbstractBuilder