Skip to content

Commit a643b91

Browse files
daniel-larrazclaude
andcommitted
Document the public API and enforce javadoc doclint
Takes the javadoc doclint warning count from 519 to zero and wires a doclint check into the build so it stays there. Twenty of the warnings were defects in existing javadoc: bare @PARAM and @throws tags with no description, a missing @PARAM on Kind2Api.execute and Result.setRealPrecision, a missing @return on Util.smtDivide, two empty <p> tags, and two {@code} blocks nested inside <code> in TypeUtil. Result.setClosingSymbols also described itself as setting the opening symbols, and Node.getName documented itself as "the name of the name". The remaining 499 were undocumented public and protected members across 67 files, now documented: the Kind 2 json labels, the Lustre pretty-printer visitors, the engine and solver enums, the result value classes, and the getters and constructors throughout the results package. Utility classes that only hold statics got private constructors, which also removes them from the generated docs. The javadoc task now passes -Xdoclint:all. Gradle always passes -quiet, which hides warning-level diagnostics and does not fail the build on them, so a separate doclintCheck task forks javadoc, reads its diagnostics and fails `check` if any are reported. Note that JDK 11's javadoc does not report missing comments at all, so the new check only bites on newer JDKs. The documentation here was verified against the JDK 25 javadoc, which does report them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 362c470 commit a643b91

68 files changed

Lines changed: 1995 additions & 28 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,63 @@ java {
2828
withSourcesJar()
2929
}
3030

31+
tasks.withType(Javadoc).configureEach {
32+
options.addBooleanOption('Xdoclint:all', true)
33+
failOnError = true
34+
}
35+
36+
// The javadoc task above runs doclint, but Gradle always passes -quiet, which
37+
// hides warning-level diagnostics such as "no comment", and it does not fail on
38+
// them. This task runs doclint separately and fails `check` if anything is
39+
// reported. Note that JDK 11's javadoc does not report missing comments at all,
40+
// so this only bites on newer JDKs; the documentation was verified against the
41+
// JDK 25 javadoc, which does report them.
42+
def doclintCheck = tasks.register('doclintCheck') {
43+
description = 'Runs javadoc doclint over the main sources and fails on any warning.'
44+
group = 'verification'
45+
dependsOn tasks.named('classes')
46+
47+
def sources = sourceSets.main.allJava
48+
def classpath = sourceSets.main.compileClasspath
49+
def workDir = layout.buildDirectory.dir('tmp/doclint')
50+
51+
inputs.files(sources)
52+
inputs.files(classpath)
53+
outputs.dir(workDir)
54+
55+
doLast {
56+
def dir = workDir.get().asFile
57+
dir.deleteDir()
58+
dir.mkdirs()
59+
60+
// The in-process javadoc ToolProvider does not honour -Xdoclint, so fork the
61+
// real javadoc executable and read its diagnostics.
62+
def argFile = new File(dir, 'sources.txt')
63+
argFile.text = sources.files.collect { it.absolutePath }.join('\n')
64+
65+
def command = ["${System.getProperty('java.home')}/bin/javadoc".toString(),
66+
'-Xdoclint:all', '-Xmaxwarns', '100000',
67+
'-classpath', classpath.asPath,
68+
'-d', new File(dir, 'out').absolutePath,
69+
'@' + argFile.absolutePath]
70+
71+
def process = new ProcessBuilder(command).redirectErrorStream(true).start()
72+
def output = process.inputStream.text
73+
def exitCode = process.waitFor()
74+
75+
def problems = output.readLines().findAll { it =~ /: (warning|error): / }
76+
if (exitCode != 0 || !problems.isEmpty()) {
77+
problems.each { logger.error(it) }
78+
throw new GradleException(
79+
"javadoc doclint reported ${problems.size()} problem(s); see the messages above.")
80+
}
81+
}
82+
}
83+
84+
tasks.named('check') {
85+
dependsOn doclintCheck
86+
}
87+
3188
publishing {
3289
publications {
3390
maven(MavenPublication) {

src/main/java/StopWatch.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
* Program.
2626
*/
2727
public class StopWatch {
28+
private StopWatch() {
29+
}
30+
2831
/**
2932
* Run the main function to print the generated Lustre program and results of calling Kind 2.
3033
*

src/main/java/edu/uiowa/cs/clc/kind2/Assert.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,43 @@
88

99
package edu.uiowa.cs.clc.kind2;
1010

11+
/**
12+
* Simple runtime assertions used to validate arguments.
13+
*/
1114
public class Assert {
15+
private Assert() {
16+
}
17+
18+
/**
19+
* Asserts that the given object is not null.
20+
*
21+
* @param o the object to check
22+
* @throws IllegalArgumentException if {@code o} is null
23+
*/
1224
public static void isNotNull(Object o) {
1325
if (o == null) {
1426
throw new Kind2Exception("Object unexpectedly null");
1527
}
1628
}
1729

30+
/**
31+
* Asserts that the given condition holds.
32+
*
33+
* @param b the condition to check
34+
* @throws IllegalArgumentException if {@code b} is false
35+
*/
1836
public static void isTrue(boolean b) {
1937
if (!b) {
2038
throw new Kind2Exception("Assertion failed");
2139
}
2240
}
2341

42+
/**
43+
* Asserts that the given condition does not hold.
44+
*
45+
* @param b the condition to check
46+
* @throws IllegalArgumentException if {@code b} is true
47+
*/
2448
public static void isFalse(boolean b) {
2549
if (b) {
2650
throw new Kind2Exception("Assertion failed");

src/main/java/edu/uiowa/cs/clc/kind2/Kind2Exception.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,21 @@
1414
public class Kind2Exception extends RuntimeException {
1515
private static final long serialVersionUID = 1L;
1616

17+
/**
18+
* Constructs an exception with the given message.
19+
*
20+
* @param message the detail message
21+
*/
1722
public Kind2Exception(String message) {
1823
super(message);
1924
}
2025

26+
/**
27+
* Constructs an exception with the given message and cause.
28+
*
29+
* @param message the detail message
30+
* @param t the underlying cause
31+
*/
2132
public Kind2Exception(String message, Throwable t) {
2233
super(message, t);
2334
}

src/main/java/edu/uiowa/cs/clc/kind2/api/ApiUtil.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,41 @@
1818
import edu.uiowa.cs.clc.kind2.Kind2Exception;
1919
import edu.uiowa.cs.clc.kind2.util.Util;
2020

21+
/**
22+
* Helpers for writing Kind 2 input files and reading its output.
23+
*/
2124
public class ApiUtil {
25+
private ApiUtil() {
26+
}
27+
28+
/**
29+
* Writes a Lustre program to a temporary file for Kind 2 to read.
30+
*
31+
* @param program the Lustre program text
32+
* @return the file the program was written to
33+
*/
2234
public static File writeLustreFile(String program) {
2335
return writeTempFile("kind2-api-", ".lus", program);
2436
}
2537

38+
/**
39+
* Writes an interpreter input to a temporary file for Kind 2 to read.
40+
*
41+
* @param program the interpreter input text
42+
* @return the file the input was written to
43+
*/
2644
public static File writeInterpreterFile(String program) {
2745
return writeTempFile("kind2-api-", ".json", program);
2846
}
2947

48+
/**
49+
* Writes the given contents to a new temporary file.
50+
*
51+
* @param fileName the base name of the file
52+
* @param fileExt the file extension, may be null
53+
* @param contents the text to write, may be null to leave the file empty
54+
* @return the newly created file
55+
*/
3056
public static File writeTempFile(String fileName, String fileExt, String contents) {
3157
File file = null;
3258
try {
@@ -40,6 +66,13 @@ public static File writeTempFile(String fileName, String fileExt, String content
4066
}
4167
}
4268

69+
/**
70+
* Reads a stream to its end.
71+
*
72+
* @param inputStream the stream to read
73+
* @return the full contents of the stream
74+
* @throws java.io.IOException if the stream cannot be read
75+
*/
4376
public static String readAll(InputStream inputStream) throws IOException {
4477
StringBuilder result = new StringBuilder();
4578
BufferedInputStream buffered = new BufferedInputStream(inputStream);
@@ -50,6 +83,12 @@ public static String readAll(InputStream inputStream) throws IOException {
5083
return result.toString();
5184
}
5285

86+
/**
87+
* Renders a command line with each argument quoted.
88+
*
89+
* @param pieces the command and its arguments
90+
* @return the quoted command line
91+
*/
5392
public static String getQuotedCommand(List<String> pieces) {
5493
return pieces.stream().map(p -> p.contains(" ") ? "\"" + p + "\"" : p).collect(joining(" "));
5594
}

src/main/java/edu/uiowa/cs/clc/kind2/api/DebugLogger.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,27 @@
1515
import edu.uiowa.cs.clc.kind2.Kind2Exception;
1616
import edu.uiowa.cs.clc.kind2.util.Util;
1717

18+
/**
19+
* Writes Kind 2 debug output to a temporary file.
20+
* <p>
21+
* A logger built with the no-argument constructor discards everything written to it.
22+
*/
1823
public class DebugLogger {
1924
private final PrintWriter debug;
2025

26+
/**
27+
* Constructs a logger that discards all output.
28+
*/
2129
public DebugLogger() {
2230
debug = null;
2331
}
2432

33+
/**
34+
* Constructs a logger writing to a new temporary file.
35+
*
36+
* @param prefix the prefix of the temporary file's name
37+
* @throws edu.uiowa.cs.clc.kind2.Kind2Exception if the file cannot be created
38+
*/
2539
public DebugLogger(String prefix) {
2640
try {
2741
File debugFile = File.createTempFile(prefix, ".txt");
@@ -31,18 +45,32 @@ public DebugLogger(String prefix) {
3145
}
3246
}
3347

48+
/**
49+
* Writes an empty line.
50+
*/
3451
public void println() {
3552
if (debug != null) {
3653
debug.println();
3754
}
3855
}
3956

57+
/**
58+
* Writes a line of text.
59+
*
60+
* @param text the text to write
61+
*/
4062
public void println(String text) {
4163
if (debug != null) {
4264
debug.println(text);
4365
}
4466
}
4567

68+
/**
69+
* Writes a line of text followed by the contents of a file.
70+
*
71+
* @param text the text to write
72+
* @param file the file whose contents to append
73+
*/
4674
public void println(String text, File file) {
4775
if (debug != null) {
4876
try {
@@ -53,6 +81,14 @@ public void println(String text, File file) {
5381
}
5482
}
5583

84+
/**
85+
* Saves the given contents to a temporary file for later inspection.
86+
*
87+
* @param prefix the prefix of the file's name
88+
* @param suffix the suffix of the file's name
89+
* @param contents the text to write
90+
* @return the file written, or null if debugging is off
91+
*/
5692
public File saveFile(String prefix, String suffix, String contents) {
5793
if (debug != null) {
5894
try {
@@ -67,6 +103,11 @@ public File saveFile(String prefix, String suffix, String contents) {
67103
}
68104
}
69105

106+
/**
107+
* Deletes a file unless debugging is enabled, in which case it is kept.
108+
*
109+
* @param file the file to delete
110+
*/
70111
public void deleteIfUnneeded(File file) {
71112
if (debug == null && file != null && file.exists()) {
72113
file.delete();

src/main/java/edu/uiowa/cs/clc/kind2/api/ITPSolverOption.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,30 @@
77

88
package edu.uiowa.cs.clc.kind2.api;
99

10+
/**
11+
* The solvers Kind 2 can use to compute interpolants.
12+
*/
1013
public enum ITPSolverOption {
11-
CVC5QE, MATHSAT, OPENSMT, SMTINTERPOL, Z3QE;
14+
/**
15+
* The cvc5 solver using quantifier elimination.
16+
*/
17+
CVC5QE,
18+
/**
19+
* The MathSAT solver.
20+
*/
21+
MATHSAT,
22+
/**
23+
* The OpenSMT solver.
24+
*/
25+
OPENSMT,
26+
/**
27+
* The SMTInterpol solver.
28+
*/
29+
SMTINTERPOL,
30+
/**
31+
* The Z3 solver using quantifier elimination.
32+
*/
33+
Z3QE;
1234

1335
@Override
1436
public String toString() {

src/main/java/edu/uiowa/cs/clc/kind2/api/IVCCategory.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,30 @@
77

88
package edu.uiowa.cs.clc.kind2.api;
99

10+
/**
11+
* The categories of model elements that may appear in an inductive validity core.
12+
*/
1013
public enum IVCCategory {
11-
NODECALLS, CONTRACTS, EQUATIONS, ASSERTIONS, ANNOTATIONS;
14+
/**
15+
* Calls to other components.
16+
*/
17+
NODECALLS,
18+
/**
19+
* Contract items such as assumptions and guarantees.
20+
*/
21+
CONTRACTS,
22+
/**
23+
* Equations defining variables.
24+
*/
25+
EQUATIONS,
26+
/**
27+
* Assertions stated in the component.
28+
*/
29+
ASSERTIONS,
30+
/**
31+
* Annotations such as the main annotation.
32+
*/
33+
ANNOTATIONS;
1234

1335
@Override
1436
public String toString() {

0 commit comments

Comments
 (0)