Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ java/dcomp_premain.jar
java/*.class
java/**/*.class
java/lib/tmp
# Directory generated when building daikon-plumelib.jar
java/lib/.gradle
# Temporary file used during compilation
java/java_files.txt
java/javadoc-files.txt
Expand Down
2 changes: 1 addition & 1 deletion java/daikon/chicory/DaikonVariableInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ protected DaikonVariableInfo addDeclVar(Field field, String offset, StringBuilde
* classes).
*/
public static @BinaryName String stdClassName(Class<?> type) {
return Runtime.classGetNameToBinaryName(type.getName());
return Signatures.classGetNameToBinaryName(type.getName());
}

/**
Expand Down
5 changes: 3 additions & 2 deletions java/daikon/chicory/DaikonWriter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package daikon.chicory;

import daikon.Chicory;
import daikon.plumelib.reflection.Signatures;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
Expand Down Expand Up @@ -164,7 +165,7 @@ private static String methodPptName(Member member, String point) {
StringJoiner param_str = new StringJoiner(", ");
for (Class<?> param : params) {
if (param.isArray()) {
param_str.add(Runtime.classGetNameToBinaryName(param.getName()));
param_str.add(Signatures.classGetNameToBinaryName(param.getName()));
} else {
param_str.add(param.getName());
}
Expand All @@ -187,7 +188,7 @@ protected boolean shouldInstrumentMethod(Member method) {
* classes).
*/
public static @BinaryName String stdClassName(Class<?> type) {
return Runtime.classGetNameToBinaryName(type.getName());
return Signatures.classGetNameToBinaryName(type.getName());
}

/** Escapes blanks and backslashes in names written to the decl/dtrace files. */
Expand Down
241 changes: 0 additions & 241 deletions java/daikon/chicory/Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,21 @@
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;
import org.checkerframework.checker.index.qual.IndexOrHigh;
import org.checkerframework.checker.lock.qual.GuardSatisfied;
import org.checkerframework.checker.lock.qual.GuardedBy;
import org.checkerframework.checker.lock.qual.Holding;
import org.checkerframework.checker.mustcall.qual.Owning;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.BinaryName;
import org.checkerframework.checker.signature.qual.ClassGetName;
import org.checkerframework.checker.signature.qual.FieldDescriptor;
import org.checkerframework.checker.signature.qual.FqBinaryName;
import org.checkerframework.checker.signature.qual.InternalForm;
import org.checkerframework.dataflow.qual.SideEffectFree;

/**
Expand Down Expand Up @@ -966,237 +958,4 @@ public static boolean isJava9orLater() {
public static boolean isJava24orLater() {
return isJava24orLater;
}

// ///////////////////////////////////////////////////////////////////////////
// Copied code
//

// This code is copied from elsewhere to make this class self-contained.

//
// From class StringsPlume
//

/**
* Escapes a String so that it is expressible in a string literal in Java source code. By
* surrounding the return value with double quote marks, the result will be a Java string literal
* denoting the original string.
*
* <p>Returns a new string only if any modifications were necessary.
*
* <p>Compared to the `escapeJava` method in Apache Commons Text StringEscapeUtils, this one
* correctly handles non-printable ASCII characters.
*
* @param orig string to quote
* @return quoted version of orig
*/
@SideEffectFree
public static String escapeJava(String orig) {
StringBuilder sb = new StringBuilder();
// The previous escape character was seen right before this position.
@IndexOrHigh("orig") int postEsc = 0;
int origLen = orig.length();
for (int i = 0; i < origLen; i++) {
char c = orig.charAt(i);
switch (c) {
case '\"':
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\\"");
postEsc = i + 1;
break;
case '\\':
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\\\");
postEsc = i + 1;
break;
case '\b':
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\b");
postEsc = i + 1;
break;
case '\f':
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\f");
postEsc = i + 1;
break;
case '\n': // not lineSep
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\n"); // not lineSep
postEsc = i + 1;
break;
case '\r':
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\r");
postEsc = i + 1;
break;
case '\t':
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\t");
postEsc = i + 1;
break;

default:
if (c >= ' ' && c <= '~') {
// Nothing to do: i gets incremented
} else if (c <= '\377') {
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append('\\');
int cAsInt = (int) c;
sb.append(String.format("%03o", cAsInt));
postEsc = i + 1;
break;
} else {
if (postEsc < i) {
sb.append(orig.substring(postEsc, i));
}
sb.append("\\u");
sb.append(String.format("%04x", (int) c));
postEsc = i + 1;
break;
}
}
}
if (sb.length() == 0) {
return orig;
}
sb.append(orig.substring(postEsc));
return sb.toString();
}

//
// From class SignaturesUtil
//

// Eventually the code should use the library rather than copying its code.
// (As of 2026-01-10, I'm having trouble with the shadowJar plugin.)

/** A map from field descriptor (such as "I") to Java primitive type (such as "int"). */
private static HashMap<String, String> fieldDescriptorToPrimitive = new HashMap<>(8);

static {
fieldDescriptorToPrimitive.put("Z", "boolean");
fieldDescriptorToPrimitive.put("B", "byte");
fieldDescriptorToPrimitive.put("C", "char");
fieldDescriptorToPrimitive.put("D", "double");
fieldDescriptorToPrimitive.put("F", "float");
fieldDescriptorToPrimitive.put("I", "int");
fieldDescriptorToPrimitive.put("J", "long");
fieldDescriptorToPrimitive.put("S", "short");
}

/** Matches the "[[[" prefix of a field descriptor for an array. */
private static Pattern fdArrayBracketsPattern = Pattern.compile("^\\[+");

// does not convert "V" to "void". Should it?
/**
* Convert a field descriptor to a binary name. For example, convert "Ljava/util/Map$Entry;" to
* "java.util.Map$Entry".
*
* <p>Strictly speaking, there is no binary name for primitives and arrays. In those cases, the
* result is a "fully-qualified binary name" ({@code @}{@link FqBinaryName}). For example, this
* method converts "[Ljava/util/Map$Entry;" to "java.util.Map$Entry[]" and converts "I" to "int".
*
* @param typename a field descriptor (the name of a type in JVML format)
* @return the corresponding binary name
*/
@SuppressWarnings("signature") // conversion routine
public static @BinaryName String fieldDescriptorToBinaryName(@FieldDescriptor String typename) {
if (typename.equals("")) {
throw new Error("Empty string passed to fieldDescriptorToBinaryName");
}
Matcher m = fdArrayBracketsPattern.matcher(typename);
String classname = m.replaceFirst("");
int dimensions = typename.length() - classname.length();
String result;
if (classname.startsWith("L") && classname.endsWith(";")) {
result = classname.substring(1, classname.length() - 1);
} else {
result = fieldDescriptorToPrimitive.get(classname);
if (result == null) {
throw new Error(
"Malformed field descriptor should be \"L...;\" or a primitive: " + classname);
}
}
for (int i = 0; i < dimensions; i++) {
result += "[]";
}
return result.replace('/', '.');
}

/**
* Convert a name in Class.getName format to a binary name. For example, convert
* "[Ljava.util.Map$Entry;" to "java.util.Map$Entry[]".
*
* @param typename a name in Class.getName format
* @return the corresponding binary name
*/
@SuppressWarnings("signature") // conversion routine
public static @BinaryName String classGetNameToBinaryName(@ClassGetName String typename) {
if (typename.equals("")) {
throw new Error("Empty string passed to classGetNameToBinaryName");
}
Matcher m = fdArrayBracketsPattern.matcher(typename);
String classname = m.replaceFirst("");
int dimensions = typename.length() - classname.length();
String result;
if (dimensions == 0) {
return classname;
} else {
if (classname.startsWith("L") && classname.endsWith(";")) {
result = classname.substring(1, classname.length() - 1);
} else {
result = fieldDescriptorToPrimitive.get(classname);
if (result == null) {
throw new Error(
"Malformed Class.getName array base type should be \"L...;\" or a primitive: "
+ classname);
}
}
for (int i = 0; i < dimensions; i++) {
result += "[]";
}
return result;
}
}

/**
* Given a class name in internal form, return it as a binary name.
*
* @param internalForm a class name in internal form
* @return the class name as a binary name
*/
public static @BinaryName String internalFormToBinaryName(@InternalForm String internalForm) {
return internalForm.replace('/', '.');
}

/**
* Given a class name in binary name form, return it in internal form.
*
* @param binaryName a class name in binary name form
* @return the class name in internal form
*/
public static @InternalForm String binaryNameToInternalForm(@BinaryName String binaryName) {
return binaryName.replace('.', '/');
}

// ///////////////////////////////////////////////////////////////////////////
// end of copied code
//

}
5 changes: 3 additions & 2 deletions java/daikon/chicory/StringInfo.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package daikon.chicory;

import daikon.plumelib.util.StringsPlume;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -67,7 +68,7 @@ public static String getStringList(List<?> theValues) {
if (str == null) {
buf.add("null");
} else if (str instanceof String) {
buf.add("\"" + Runtime.escapeJava((String) str) + "\"");
buf.add("\"" + StringsPlume.escapeJava((String) str) + "\"");
} else if (str instanceof NonsensicalObject || str instanceof NonsensicalList) {
buf.add("nonsensical");
} else {
Expand Down Expand Up @@ -111,7 +112,7 @@ public String getValueStringNonArr(Object val) {
* @return the quoted string
*/
private String getString(String stringRef) {
return "\"" + Runtime.escapeJava(stringRef) + "\"";
return "\"" + StringsPlume.escapeJava(stringRef) + "\"";
}

/** toString is a function. */
Expand Down
5 changes: 2 additions & 3 deletions java/daikon/dcomp/ClassGen24.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package daikon.dcomp;

import daikon.chicory.Runtime;
import daikon.plumelib.reflection.Signatures;
import java.lang.classfile.AccessFlags;
import java.lang.classfile.ClassBuilder;
Expand Down Expand Up @@ -100,7 +99,7 @@ public ClassGen24(
* @param name the interface name, in binary format
*/
public void addInterface(@BinaryName String name) {
String internalName = Runtime.binaryNameToInternalForm(name);
String internalName = Signatures.binaryNameToInternalForm(name);
for (ClassEntry existing : interfaceList) {
if (existing.asInternalName().equals(internalName)) {
return;
Expand Down Expand Up @@ -197,7 +196,7 @@ public final boolean isStatic() {
public static @BinaryName String getSuperclassName(ClassModel classModel) {
Optional<ClassEntry> ce = classModel.superclass();
if (ce.isPresent()) {
return Runtime.internalFormToBinaryName(ce.get().asInternalName());
return Signatures.internalFormToBinaryName(ce.get().asInternalName());
} else {
return "java.lang.Object";
}
Expand Down
Loading
Loading