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:*)",
"Edit(./**)",
"Read(//home/mernst/research/types/checker-framework-fork*/**)",
"Read(//scratch/**)",
Expand All @@ -28,5 +29,5 @@
"deny": [],
"ask": []
},
"skipDangerousModePermissionPrompt": false
"skipDangerousModePermissionPrompt": true
}
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)
- name: ./gradlew build
run: ./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: ./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
36 changes: 14 additions & 22 deletions src/main/java/org/plumelib/reflection/ReflectionPlume.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -170,12 +170,13 @@ public static String nameWithoutPackage(Class<?> c) {
return c.getSimpleName();
}

StringBuilder result = new StringBuilder(c.getSimpleName());
while (enclosing != null) {
result.insert(0, enclosing.getSimpleName() + ".");
enclosing = enclosing.getEnclosingClass();
ArrayDeque<String> parts = new ArrayDeque<>();
Class<?> current = c;
while (current != null) {
parts.addFirst(current.getSimpleName());
current = current.getEnclosingClass();
}
return result.toString();
return String.join(".", parts);
}

// //////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -204,26 +205,20 @@ public PromiscuousLoader() {}
*/
public Class<?> defineClassFromFile(@BinaryName String className, String pathname)
throws FileNotFoundException, IOException {
int numbytes;
byte[] classBytes;
int bytesRead;
try (InputStream fi = Files.newInputStream(Path.of(pathname))) {
numbytes = fi.available();
classBytes = new byte[numbytes];
bytesRead = fi.read(classBytes);
}
if (bytesRead < numbytes) {
throw new Error(
"Expected to read %d bytes from %s, got %d".formatted(numbytes, pathname, bytesRead));
try {
classBytes = Files.readAllBytes(Path.of(pathname));
} catch (java.nio.file.NoSuchFileException e) {
throw new FileNotFoundException(pathname);
}
Class<?> returnClass = defineClass(className, classBytes, 0, numbytes);
Class<?> returnClass = defineClass(className, classBytes, 0, classBytes.length);
resolveClass(returnClass); // link the class
return returnClass;
}
}

/** A ClassLoader that can call defineClassFromFile. */
private static PromiscuousLoader thePromiscuousLoader = new PromiscuousLoader();
private static final PromiscuousLoader thePromiscuousLoader = new PromiscuousLoader();

/**
* Converts the bytes in a file into an instance of class Class, and resolves (links) the class.
Expand Down Expand Up @@ -256,7 +251,6 @@ public static Class<?> defineClassFromFile(@BinaryName String className, String
public static void addToClasspath(String dir) {
// If the dir isn't on CLASSPATH, add it.
String pathSep = System.getProperty("path.separator");
// what is the point of the "replace()" call?
String cp = System.getProperty("java.class.path", ".").replace('\\', '/');
StringTokenizer tokenizer = new StringTokenizer(cp, pathSep, false);
boolean found = false;
Expand Down Expand Up @@ -287,7 +281,7 @@ public static String classpathToString() {
* array of Class objects, one for each arg type. Example keys include: "java.lang.String,
* java.lang.String, java.lang.Class[]" and "int,int".
*/
static HashMap<String, Class<?>[]> args_seen = new HashMap<>();
private static final HashMap<String, Class<?>[]> args_seen = new HashMap<>();

/**
* Given a method signature, return the method.
Expand Down Expand Up @@ -402,7 +396,6 @@ public static void setFinalField(Object o, String fieldName, @Interned Object va
throws NoSuchFieldException {
Class<?> c = o.getClass();
while (c != Object.class) { // Class is interned
// System.out.printf ("Setting field %s in %s%n", fieldName, c);
try {
Field f = c.getDeclaredField(fieldName);
@SuppressWarnings("deprecation") // No non-deprecated alternative to query accessible flag.
Expand Down Expand Up @@ -439,7 +432,6 @@ public static void setFinalField(Object o, String fieldName, @Interned Object va
throws NoSuchFieldException {
Class<?> c = o.getClass();
while (c != Object.class) { // Class is interned
// System.out.printf ("Setting field %s in %s%n", fieldName, c);
try {
Field f = c.getDeclaredField(fieldName);
@SuppressWarnings("deprecation") // No non-deprecated alternative to query accessible flag.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ private SignatureRegexes() {
Pattern.compile(FieldDescriptorWithoutPackageRegex);

/** An anchored regex that matches FieldDescriptorForPrimitive strings. */
public static final @Regex String FieldDescriptorForPrimitiveRegex = ANCHORED("^[BCDFIJSZ]$");
public static final @Regex String FieldDescriptorForPrimitiveRegex = ANCHORED("[BCDFIJSZ]");

/** An anchored pattern that matches FieldDescriptorForPrimitive strings. */
public static final Pattern FieldDescriptorForPrimitivePattern =
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/org/plumelib/reflection/Signatures.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private Signatures() {
* Returns the element type for the given type name, which results from removing all the array
* brackets.
*
* @param fqBinaryName "a fully-qualified binary name" ({@code @FqBinaryNome})
* @param fqBinaryName "a fully-qualified binary name" ({@code @FqBinaryName})
* @return the base element type of the argument, with all array brackets stripped
*/
@SuppressWarnings("signature") // @FqBinaryName = @ClassGetName plus optional array brackets
Expand Down Expand Up @@ -484,7 +484,7 @@ public static ClassnameAndDimensions parseFqBinaryName(@FqBinaryName String type
)
public static @FullyQualifiedName String binaryNameToFullyQualified(
@BinaryName String binaryName) {
return binaryName.replaceAll("\\$", ".");
return binaryName.replace('$', '.');
}

/**
Expand All @@ -502,7 +502,7 @@ public static ClassnameAndDimensions parseFqBinaryName(@FqBinaryName String type
}
}

/** A map from field descriptor (sach as "I") to Java primitive type (such as "int"). */
/** A map from field descriptor (such as "I") to Java primitive type (such as "int"). */
private static final Map<String, String> fieldDescriptorToPrimitive =
Map.of(
"Z", "boolean",
Expand Down Expand Up @@ -699,7 +699,6 @@ public static String arglistToJvm(String arglist) {
for (@BinaryName String javaArg : splitJavaArglist(arglist)) {
result.add(binaryNameToFieldDescriptor(javaArg));
}
// System.out.println("arglistToJvm: " + arglist + " => " + result);
return result.toString();
}

Expand Down