diff --git a/liquidjava-verifier/pom.xml b/liquidjava-verifier/pom.xml
index 43aa8422..f77a5e11 100644
--- a/liquidjava-verifier/pom.xml
+++ b/liquidjava-verifier/pom.xml
@@ -319,6 +319,11 @@
2.10.1
+
+ info.picocli
+ picocli
+ 4.7.7
+
diff --git a/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineArgs.java b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineArgs.java
new file mode 100644
index 00000000..9fe7d6d0
--- /dev/null
+++ b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineArgs.java
@@ -0,0 +1,20 @@
+package liquidjava.api;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+
+@Command(name = "liquidjava", mixinStandardHelpOptions = false, customSynopsis = "./liquidjava <...paths> ")
+public class CommandLineArgs {
+ @Option(names = {"-h", "--help"}, usageHelp = true, description = "Display this help message")
+ public boolean help;
+
+ @Option(names = { "-d", "--debug" }, description = "Enable debug mode for more detailed output")
+ public boolean debugMode;
+
+ @Parameters(arity = "1..*", paramLabel = "<...paths>", description = "Paths to be verified by LiquidJava")
+ public List paths;
+}
diff --git a/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java
index e473562c..796928c8 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java
@@ -2,13 +2,13 @@
import java.io.File;
import java.util.Arrays;
-import java.util.List;
import liquidjava.diagnostics.Diagnostics;
import liquidjava.diagnostics.errors.CustomError;
import liquidjava.diagnostics.warnings.CustomWarning;
import liquidjava.processor.RefinementProcessor;
import liquidjava.processor.context.ContextHistory;
+import picocli.CommandLine;
import spoon.Launcher;
import spoon.compiler.Environment;
import spoon.processing.ProcessingManager;
@@ -20,18 +20,18 @@ public class CommandLineLauncher {
private static final Diagnostics diagnostics = Diagnostics.getInstance();
private static final ContextHistory contextHistory = ContextHistory.getInstance();
+ public static final CommandLineArgs cmdArgs = new CommandLineArgs();
public static void main(String[] args) {
- if (args.length == 0) {
- System.out.println("No input paths provided");
- System.out.println("\nUsage: ./liquidjava <...paths>");
- System.out.println(" <...paths>: Paths to be verified by LiquidJava");
- System.out.println(
- "\nExample: ./liquidjava liquidjava-example/src/main/java/test liquidjava-example/src/main/java/testingInProgress/Account.java");
+ CommandLine cmd = new CommandLine(cmdArgs);
+ cmd.parseArgs(args);
+
+ if (cmd.isUsageHelpRequested()) {
+ cmd.usage(System.out);
return;
}
- List paths = Arrays.asList(args);
- launch(paths.toArray(new String[0]));
+
+ launch(cmdArgs.paths.stream().toArray(String[]::new));
// print diagnostics
if (diagnostics.foundWarning()) {
@@ -39,9 +39,10 @@ public static void main(String[] args) {
}
if (diagnostics.foundError()) {
System.out.println(diagnostics.getErrorOutput());
- } else {
- System.out.println("Correct! Passed Verification.");
+ return;
}
+
+ System.out.println("Correct! Passed Verification.");
}
public static void launch(String... paths) {
diff --git a/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java b/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java
index 39a81d92..a1ba3c3c 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java
@@ -4,6 +4,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import liquidjava.api.CommandLineLauncher;
import liquidjava.diagnostics.TranslationTable;
import liquidjava.rj_language.opt.derivation_node.ValDerivationNode;
import liquidjava.smt.Counterexample;
@@ -48,7 +49,7 @@ public String getCounterExampleString() {
found.getValue().getVariableNames(foundVarNames);
String counterexampleString = counterexample.assignments().stream()
// only include variables that appear in the found value
- .filter(a -> foundVarNames.contains(a.first()))
+ .filter(a -> CommandLineLauncher.cmdArgs.debugMode || foundVarNames.contains(a.first()))
// format as "var == value"
.map(a -> VariableFormatter.formatVariable(a.first()) + " == " + a.second())
// join with "&&"
diff --git a/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/VCChecker.java b/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/VCChecker.java
index d757f2a7..80014606 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/VCChecker.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/VCChecker.java
@@ -10,6 +10,7 @@
import java.util.stream.Collectors;
import liquidjava.diagnostics.errors.*;
+import liquidjava.api.CommandLineLauncher;
import liquidjava.diagnostics.TranslationTable;
import liquidjava.processor.VCImplication;
import liquidjava.processor.context.*;
@@ -22,6 +23,7 @@
import liquidjava.smt.SMTResult;
import liquidjava.utils.Utils;
import liquidjava.utils.constants.Keys;
+import liquidjava.utils.Utils;
import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.factory.Factory;
@@ -102,6 +104,12 @@ public void processSubtyping(Predicate type, Predicate expectedType, List