Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"Bash(python3 -m json.tool)",
"Bash(timeout 300 ./gradlew:*)",
"Bash(wc:*)",
"Bash(xargs cat:*)",
Comment thread
mernst marked this conversation as resolved.
"Edit(./**)",
"Read(//home/mernst/research/types/checker-framework-fork*/**)",
"Read(//scratch/**)",
Expand All @@ -28,5 +29,5 @@
"deny": [],
"ask": []
},
"skipDangerousModePermissionPrompt": false
"skipDangerousModePermissionPrompt": true
Comment thread
mernst marked this conversation as resolved.
}
2 changes: 2 additions & 0 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ jobs:
cache: 'gradle'
- name: java -version
run: java -version
- name: Warm up Gradle cache
run: ./gradlew spotlessCheck > /dev/null 2>&1 || (sleep 60 && true)
Comment thread
mernst marked this conversation as resolved.
- name: ./gradlew build
run: _JAVA_OPTIONS=-Xmx2g ./gradlew build
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ jdk:
- openjdk21
- openjdk25

# Add "verGJF" task when google-java-format handles type annotations better;
# see https://github.com/google/google-java-format/issues/5
script: export CHECKERFRAMEWORK="/tmp/checker-framework" && ./gradlew build

git:
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
alias(libs.plugins.com.gradleup.shadow)

// Code formatting; defines targets "spotlessApply" and "spotlessCheck"
// which is run by "check" (which is itself run by "build").
alias(libs.plugins.com.diffplug.spotless)

// Error Prone linter
Expand Down
57 changes: 30 additions & 27 deletions src/main/java/org/plumelib/options/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
*
* <p><b>Generating documentation for a manual or manpage</b>
*
* <p>It is helpful to include a summary of all command-line options in amanual, manpage, or the
* <p>It is helpful to include a summary of all command-line options in a manual, manpage, or the
* class Javadoc for a class that has a main method. The {@link org.plumelib.options.OptionsDoclet}
* class generates HTML documentation.
*
Expand Down Expand Up @@ -354,10 +354,11 @@ public void enableDebugLogging(boolean enabled) {
}

/** All of the argument options as a single string. Used for debugging. */
private String optionsString = "";
@SuppressWarnings("PMD.AvoidStringBufferField")
private StringBuilder optionsString = new StringBuilder();

/** The system-dependent line separator. */
private static String lineSeparator = System.lineSeparator();
private static final String lineSeparator = System.lineSeparator();

/** Information about an option. */
@SuppressWarnings("PMD.TooManyFields")
Expand Down Expand Up @@ -691,9 +692,9 @@ public Options(@UnknownInitialization Object... args) {

/**
* Prepare for option processing. Creates an object that will set fields in all the given
* arguments. An argument to this method may be a Class, in which case it must be fully initalized
* and its static fields are set. The names of all the options (that is, the fields annotated with
* &#064;{@link Option}) must be unique across all the arguments.
* arguments. An argument to this method may be a Class, in which case it must be fully
* initialized and its static fields are set. The names of all the options (that is, the fields
* annotated with &#064;{@link Option}) must be unique across all the arguments.
*
* @param usageSynopsis a synopsis of how to call your program
* @param args the classes whose options to process
Expand Down Expand Up @@ -1015,7 +1016,7 @@ public String[] parse(String[] args) throws ArgException {
for (int ii = 0; ii < args.length; ) {
// If there was a ',' separator in previous arg, use the tail as
// current arg; otherwise, fetch the next arg from args list.
if (tail.length() > 0) {
if (!tail.isEmpty()) {
arg = tail;
tail = "";
} else {
Expand All @@ -1032,7 +1033,7 @@ public String[] parse(String[] args) throws ArgException {
// some command line quoting problems. (markro)
int splitPos = arg.indexOf(",-");
if (splitPos == 0) {
// Just discard the ',' if ",-" occurs at begining of string
// Just discard the ',' if ",-" occurs at beginning of string
arg = arg.substring(1);
splitPos = arg.indexOf(",-");
}
Expand Down Expand Up @@ -1084,7 +1085,7 @@ public String[] parse(String[] args) throws ArgException {
}

// If no ',' tail, advance to next args option
if (tail.length() == 0) {
if (tail.isEmpty()) {
ii++;
}
}
Expand Down Expand Up @@ -1128,8 +1129,8 @@ public String[] parse(String message, String[] args) {
* Sets option variables from the given command line; if any command-line argument is illegal,
* prints the usage message and terminates the program.
*
* <p>If an error occurs and {@code showUsageOnError} is true, prints the exception's message,
* prints usage inoframtion, and then terminates the program. The program is terminated rather
* <p>If an error occurs, prints the exception's message, and if {@code showUsageOnError} is true,
* prints usage information, and then terminates the program. The program is terminated rather
* than throwing an error to create cleaner output.
*
* @param showUsageOnError if a command-line argument is incorrect, print a usage message
Expand All @@ -1148,15 +1149,16 @@ public String[] parse(boolean showUsageOnError, String[] args) {
if (exceptionMessage != null) {
System.out.println(exceptionMessage);
}
printUsage();
if (showUsageOnError) {
printUsage();
}
System.exit(-1);
// throw new Error ("usage error: ", ae);
}
return nonOptions;
}

/**
* True if some documented option accepts a list as a parameter. Used and set by {code usage()}
* True if some documented option accepts a list as a parameter. Used and set by {@code usage()}
* methods and their callees.
*/
private boolean hasListOption = false;
Expand Down Expand Up @@ -1227,7 +1229,7 @@ public String usage(boolean showUnpublicized, String... groupNames) {
throw new IllegalArgumentException(
"group does not contain any publicized options: " + groupName);
} else {
groups.add(groupNameToOptionGroup.get(groupName));
groups.add(gi);
}
}
} else { // return usage for all groups that are not unpublicized
Expand All @@ -1239,11 +1241,10 @@ public String usage(boolean showUnpublicized, String... groupNames) {
}
}

List<Integer> lengths = new ArrayList<>();
int maxLength = 0;
for (OptionGroupInfo gi : groups) {
lengths.add(maxOptionLength(gi.optionList, showUnpublicized));
maxLength = Math.max(maxLength, maxOptionLength(gi.optionList, showUnpublicized));
}
int maxLength = Collections.max(lengths);

StringJoiner buf = new StringJoiner(lineSeparator);
for (OptionGroupInfo gi : groups) {
Expand Down Expand Up @@ -1368,18 +1369,17 @@ private void setArg(OptionInfo oi, String argName, @Nullable String argValue)
Field f = oi.field;
Class<?> type = oi.baseType;

// Keep track of all of the options specified
if (optionsString.length() > 0) {
optionsString += " ";
if (!optionsString.isEmpty()) {
optionsString.append(' ');
}
optionsString += argName;
optionsString.append(argName);
if (argValue != null) {
if (!argValue.contains(" ")) {
optionsString += "=" + argValue;
optionsString.append('=').append(argValue);
} else if (!argValue.contains("'")) {
optionsString += "='" + argValue + "'";
optionsString.append("='").append(argValue).append('\'');
} else if (!argValue.contains("\"")) {
optionsString += "=\"" + argValue + "\"";
optionsString.append("=\"").append(argValue).append('"');
} else {
throw new ArgException("Can't quote for internal debugging: " + argValue);
}
Expand Down Expand Up @@ -1577,7 +1577,7 @@ private <T extends Enum<T>> T getEnumValue(Class<T> enumType, String name) {
* simple name of the type, but there are special cases (for files, regular expressions, enums,
* ...).
*
* @param type the type whoso short name to return
* @param type the type whose short name to return
* @return a short name for the specified type for use in messages
*/
private static String typeShortName(Class<?> type) {
Expand All @@ -1604,7 +1604,7 @@ private static String typeShortName(Class<?> type) {
* @see #settings()
*/
public String getOptionsString() {
return optionsString;
return optionsString.toString();
}

// TODO: document what this is good for. Debugging? Invoking other programs?
Expand Down Expand Up @@ -1638,6 +1638,9 @@ public String settings(boolean showUnpublicized) {

// Create the settings string
for (OptionInfo oi : options) {
if (oi.unpublicized && !showUnpublicized) {
continue;
}
@SuppressWarnings("formatter") // format string computed from maxLength
String use =
String.format("%-" + maxLength + "s = %s", oi.longName, fieldGet(oi.field, oi.obj));
Expand Down
73 changes: 33 additions & 40 deletions src/main/java/org/plumelib/options/OptionsDoclet.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.StringJoiner;
import javax.lang.model.SourceVersion;
Expand Down Expand Up @@ -152,7 +151,7 @@
* "America/Chicago"}, which is incorrect for users elsewhere. Using {@code noDocDefault} keeps the
* HTML documentation system-agnostic.
*
* <p><b>Uppublicized options</b>
* <p><b>Unpublicized options</b>
*
* <p>The generated HTML documentation omits {@code @}{@link Unpublicized} options. It includes
* unpublicized option groups if they contain any publicized options.
Expand All @@ -175,7 +174,7 @@
public class OptionsDoclet implements Doclet {

/** The system-specific line separator. */
private static String lineSep = System.lineSeparator();
private static final String lineSep = System.lineSeparator();

/** How to use the Options doclet. */
private static final String USAGE =
Expand Down Expand Up @@ -229,7 +228,7 @@ public class OptionsDoclet implements Doclet {
/** The command-line options. */
private Options options;

/** The DocTrees instance assocated with {@link #denv}. */
/** The DocTrees instance associated with {@link #denv}. */
private DocTrees docTrees;

/** Used to report errors. */
Expand All @@ -240,9 +239,7 @@ public class OptionsDoclet implements Doclet {
"nullness:initialization.fields.uninitialized", // init() sets reporter, run() sets denv
"initializedfields:contracts.postcondition" // init() sets reporter, run() sets denv
})
public OptionsDoclet() {
// this.options = options;
}
public OptionsDoclet() {}

// //////////////////////////////////////////////////////////////////////
// Doclet-specific methods
Expand Down Expand Up @@ -529,7 +526,7 @@ public boolean process(String option, List<String> arguments) {
});

/**
* Sets variables that can only be set after all command-line options have been processed. Isuses
* Sets variables that can only be set after all command-line options have been processed. Issues
* errors and halts if any command-line options are incompatible with one another.
*/
private void postprocessOptions() {
Expand All @@ -547,17 +544,13 @@ private void postprocessOptions() {
hasError = true;
}
if (inPlace && docFile == null) {
printError("-i supplied but -docfile was not");
printError("-i supplied but --docfile was not");
hasError = true;
}
if (docFile != null && outFile != null && outFile.equals(docFile)) {
printError("--docfile must be different from --outfile");
hasError = true;
}
if (inPlace && docFile == null) {
printError("-i supplied but --docfile was not");
hasError = true;
}
if (hasError) {
System.err.println(USAGE);
System.exit(1);
Expand Down Expand Up @@ -690,35 +683,40 @@ private String newDocFileText() {
//

/**
* Returns the fields defined by the given type.
* Returns the enclosed elements of the given type that have the given kind.
*
* @param type a type
* @return the fields defined by the given type
* @param kind the kind of elements to return
* @return the enclosed elements of the given type that have the given kind
*/
private List<VariableElement> fields(TypeElement type) {
private List<VariableElement> enclosedElementsOfKind(TypeElement type, ElementKind kind) {
List<VariableElement> result = new ArrayList<>();
for (Element ee : type.getEnclosedElements()) {
if (ee.getKind() == ElementKind.FIELD) {
if (ee.getKind() == kind) {
result.add((VariableElement) ee);
}
}
return result;
}

/**
* Returns the fields defined by the given type.
*
* @param type a type
* @return the fields defined by the given type
*/
private List<VariableElement> fields(TypeElement type) {
return enclosedElementsOfKind(type, ElementKind.FIELD);
}

/**
* Returns the enum constants defined by the given type.
*
* @param type a type
* @return the enum constants defined by the given type
*/
private List<VariableElement> enumConstants(TypeElement type) {
List<VariableElement> result = new ArrayList<>();
for (Element ee : type.getEnclosedElements()) {
if (ee.getKind() == ElementKind.ENUM_CONSTANT) {
result.add((VariableElement) ee);
}
}
return result;
return enclosedElementsOfKind(type, ElementKind.ENUM_CONSTANT);
}

/** Adds Javadoc info to each option in {@code options.getOptions()}. */
Expand Down Expand Up @@ -858,18 +856,15 @@ public String optionsToHtml(int refillWidth) {
*/
public String optionsToJavadoc(int padding, int refillWidth) {
StringJoiner b = new StringJoiner(lineSep);
try (Scanner s = new Scanner(optionsToHtml(refillWidth - padding - 2))) {
while (s.hasNextLine()) {
String line = s.nextLine();
StringBuilder bb = new StringBuilder();
bb.append(StringUtils.repeat(' ', padding));
if (line.trim().equals("")) {
bb.append('*');
} else {
bb.append("* ").append(line);
}
b.add(bb);
for (String line : optionsToHtml(refillWidth - padding - 2).lines().toList()) {
StringBuilder bb = new StringBuilder();
bb.append(StringUtils.repeat(' ', padding));
if (line.isBlank()) {
bb.append('*');
} else {
bb.append("* ").append(line);
}
b.add(bb);
}

return b.toString();
Expand Down Expand Up @@ -956,10 +951,8 @@ private String refill(String in, int padding, int firstLinePadding, int refillWi
}
multiLine.add(oneLine);
if (suffix != null) {
try (Scanner s = new Scanner(suffix)) {
while (s.hasNextLine()) {
multiLine.add(StringUtils.repeat(" ", padding) + s.nextLine());
}
for (String line : suffix.lines().toList()) {
multiLine.add(StringUtils.repeat(" ", padding) + line);
}
}
return multiLine.toString();
Expand All @@ -969,7 +962,7 @@ private String refill(String in, int padding, int firstLinePadding, int refillWi
* Returns the line of HTML describing one Option.
*
* @param oi the option to describe
* @param padding the number of spaces to add at the begginning of the detail line (after the line
* @param padding the number of spaces to add at the beginning of the detail line (after the line
* with the option itself)
* @return HTML describing oi
*/
Expand Down