From 1a9edb8df9c1da9eb0178aa53be748828dc7835e Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Tue, 13 Jun 2023 08:57:47 +0000 Subject: [PATCH] 8309838: Classfile API Util.toBinaryName and other cleanup Reviewed-by: asotona --- .../classfile/ClassHierarchyResolver.java | 2 +- .../classfile/impl/ClassHierarchyImpl.java | 5 +- .../jdk/internal/classfile/impl/Util.java | 71 +++---------------- test/jdk/jdk/classfile/UtilTest.java | 13 +--- 4 files changed, 15 insertions(+), 76 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/ClassHierarchyResolver.java b/src/java.base/share/classes/jdk/internal/classfile/ClassHierarchyResolver.java index 161d15a7152..45c9058e72d 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/ClassHierarchyResolver.java +++ b/src/java.base/share/classes/jdk/internal/classfile/ClassHierarchyResolver.java @@ -196,7 +196,7 @@ public interface ClassHierarchyResolver { @Override public Class apply(ClassDesc cd) { try { - return Class.forName(Util.toBinaryName(cd.descriptorString()), false, loader); + return Class.forName(Util.toBinaryName(cd), false, loader); } catch (ClassNotFoundException ex) { return null; } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java index 5069f8bbc08..9959f65cdee 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java @@ -120,7 +120,8 @@ public final class ClassHierarchyImpl { } public static final class CachedClassHierarchyResolver implements ClassHierarchyResolver { - //this instance should leak out, appears only in cache in order to utilize Map.computeIfAbsent + // this instance should not leak out, appears only in cache in order to utilize Map.computeIfAbsent + // is already an invalid combination, so it can be compared with equals or as value class safely private static final ClassHierarchyResolver.ClassHierarchyInfo NOPE = new ClassHierarchyInfoImpl(null, true); @@ -221,7 +222,7 @@ public final class ClassHierarchyImpl { @Override public Class apply(ClassDesc cd) { try { - return Class.forName(Util.toBinaryName(cd.descriptorString()), false, ClassLoader.getSystemClassLoader()); + return Class.forName(Util.toBinaryName(cd), false, ClassLoader.getSystemClassLoader()); } catch (ClassNotFoundException ex) { return null; } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java index d4ee49aca6e..b757749b498 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java @@ -54,10 +54,6 @@ public class Util { private Util() { } - public static String arrayOf(CharSequence s) { - return "[" + s; - } - public static int parameterSlots(MethodTypeDesc mDesc) { int count = 0; for (int i = 0; i < mDesc.parameterCount(); i++) { @@ -85,70 +81,19 @@ public class Util { } /** - * Convert a descriptor of classes or interfaces or arrays, or an internal - * name of a class or interface, into a fully qualified binary name, that can - * be resolved by {@link Class#forName(String) Class::forName}. Primitive type - * descriptors should never be passed into this method. - * - * @param descOrInternalName a descriptor or internal name - * @return the fully qualified binary name + * Converts a descriptor of classes or interfaces into + * a binary name. Rejects primitive types or arrays. + * This is an inverse of {@link ClassDesc#of(String)}. */ - public static String toBinaryName(String descOrInternalName) { - if (descOrInternalName.startsWith("L")) { - // descriptors of classes or interfaces - if (descOrInternalName.length() <= 2 || !descOrInternalName.endsWith(";")) { - throw new IllegalArgumentException(descOrInternalName); - } - return descOrInternalName.substring(1, descOrInternalName.length() - 1).replace('/', '.'); - } else { - // arrays, classes or interfaces' internal names - return descOrInternalName.replace('/', '.'); - } - } - - public static Iterator parameterTypes(String s) { - //TODO: gracefully non-method types - return new Iterator<>() { - int ch = 1; - - @Override - public boolean hasNext() { - return s.charAt(ch) != ')'; - } - - @Override - public String next() { - char curr = s.charAt(ch); - switch (curr) { - case 'C', 'B', 'S', 'I', 'J', 'F', 'D', 'Z': - ch++; - return String.valueOf(curr); - case '[': - ch++; - return "[" + next(); - case 'L': { - int start = ch; - while (s.charAt(++ch) != ';') { } - ++ch; - return s.substring(start, ch); - } - default: - throw new AssertionError("cannot parse string: " + s); - } - } - }; - } - - public static String returnDescriptor(String s) { - return s.substring(s.indexOf(')') + 1); + public static String toBinaryName(ClassDesc cd) { + return toInternalName(cd).replace('/', '.'); } public static String toInternalName(ClassDesc cd) { var desc = cd.descriptorString(); - return switch (desc.charAt(0)) { - case 'L' -> desc.substring(1, desc.length() - 1); - default -> throw new IllegalArgumentException(desc); - }; + if (desc.charAt(0) == 'L') + return desc.substring(1, desc.length() - 1); + throw new IllegalArgumentException(desc); } public static ClassDesc toClassDesc(String classInternalNameOrArrayDesc) { diff --git a/test/jdk/jdk/classfile/UtilTest.java b/test/jdk/jdk/classfile/UtilTest.java index 2790213acfa..8dea7496283 100644 --- a/test/jdk/jdk/classfile/UtilTest.java +++ b/test/jdk/jdk/classfile/UtilTest.java @@ -46,20 +46,13 @@ class UtilTest { Object.class, Util.class, Test.class, - int[][].class, - Object[].class, }) void testDescToBinaryName(Class type) throws ReflectiveOperationException { - if (!type.isArray()) { - // Test internal name - var internal = type.getName().replace('.', '/'); - assertEquals(type, Class.forName(Util.toBinaryName(internal))); - } - // Test descriptor - assertEquals(type, Class.forName(Util.toBinaryName(type.descriptorString()))); + var cd = type.describeConstable().orElseThrow(); + assertEquals(type, Class.forName(Util.toBinaryName(cd))); + assertEquals(type.getName(), Util.toBinaryName(cd)); } - @Test void testParameterSlots() { assertSlots("(IIII)V", 4);