8278863: Add method ClassDesc::ofInternalName
Reviewed-by: jvernee
This commit is contained in:
parent
4020ed53dd
commit
0fa7d9e8cd
@ -72,12 +72,39 @@ public sealed interface ClassDesc
|
||||
* @throws NullPointerException if the argument is {@code null}
|
||||
* @throws IllegalArgumentException if the name string is not in the
|
||||
* correct format
|
||||
* @see ClassDesc#ofDescriptor(String)
|
||||
* @see ClassDesc#ofInternalName(String)
|
||||
*/
|
||||
static ClassDesc of(String name) {
|
||||
ConstantUtils.validateBinaryClassName(requireNonNull(name));
|
||||
return ClassDesc.ofDescriptor("L" + binaryToInternal(name) + ";");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@linkplain ClassDesc} for a class or interface type,
|
||||
* given the name of the class or interface in internal form,
|
||||
* such as {@code "java/lang/String"}.
|
||||
*
|
||||
* @apiNote
|
||||
* To create a descriptor for an array type, either use {@link #ofDescriptor(String)}
|
||||
* or {@link #arrayType()}; to create a descriptor for a primitive type, use
|
||||
* {@link #ofDescriptor(String)} or use the predefined constants in
|
||||
* {@link ConstantDescs}.
|
||||
*
|
||||
* @param name the fully qualified class name, in internal (slash-separated) form
|
||||
* @return a {@linkplain ClassDesc} describing the desired class
|
||||
* @throws NullPointerException if the argument is {@code null}
|
||||
* @throws IllegalArgumentException if the name string is not in the
|
||||
* correct format
|
||||
* @jvms 4.2.1 Binary Class and Interface Names
|
||||
* @see ClassDesc#of(String)
|
||||
* @see ClassDesc#ofDescriptor(String)
|
||||
*/
|
||||
static ClassDesc ofInternalName(String name) {
|
||||
ConstantUtils.validateInternalClassName(requireNonNull(name));
|
||||
return ClassDesc.ofDescriptor("L" + name + ";");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@linkplain ClassDesc} for a class or interface type,
|
||||
* given a package name and the unqualified (simple) name for the
|
||||
@ -125,6 +152,8 @@ public sealed interface ClassDesc
|
||||
* correct format
|
||||
* @jvms 4.3.2 Field Descriptors
|
||||
* @jvms 4.4.1 The CONSTANT_Class_info Structure
|
||||
* @see ClassDesc#of(String)
|
||||
* @see ClassDesc#ofInternalName(String)
|
||||
*/
|
||||
static ClassDesc ofDescriptor(String descriptor) {
|
||||
requireNonNull(descriptor);
|
||||
|
@ -58,6 +58,23 @@ class ConstantUtils {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the correctness of an internal class name.
|
||||
* In particular checks for the presence of invalid characters in the name.
|
||||
*
|
||||
* @param name the class name
|
||||
* @return the class name passed if valid
|
||||
* @throws IllegalArgumentException if the class name is invalid
|
||||
*/
|
||||
static String validateInternalClassName(String name) {
|
||||
for (int i=0; i<name.length(); i++) {
|
||||
char ch = name.charAt(i);
|
||||
if (ch == ';' || ch == '[' || ch == '.')
|
||||
throw new IllegalArgumentException("Invalid class name: " + name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a member name
|
||||
*
|
||||
|
@ -133,6 +133,7 @@ public class ClassDescTest extends SymbolicDescTest {
|
||||
public void testSimpleClassDesc() throws ReflectiveOperationException {
|
||||
|
||||
List<ClassDesc> stringClassDescs = Arrays.asList(ClassDesc.ofDescriptor("Ljava/lang/String;"),
|
||||
ClassDesc.ofInternalName("java/lang/String"),
|
||||
ClassDesc.of("java.lang", "String"),
|
||||
ClassDesc.of("java.lang.String"),
|
||||
ClassDesc.of("java.lang.String").arrayType().componentType(),
|
||||
@ -149,6 +150,9 @@ public class ClassDescTest extends SymbolicDescTest {
|
||||
testClassDesc(ClassDesc.of("java.lang.String").arrayType(), String[].class);
|
||||
testClassDesc(ClassDesc.of("java.util.Map").nested("Entry"), Map.Entry.class);
|
||||
|
||||
assertEquals(ClassDesc.of("java.lang.String"), ClassDesc.ofDescriptor("Ljava/lang/String;"));
|
||||
assertEquals(ClassDesc.of("java.lang.String"), ClassDesc.ofInternalName("java/lang/String"));
|
||||
|
||||
ClassDesc thisClassDesc = ClassDesc.ofDescriptor("LClassDescTest;");
|
||||
assertEquals(thisClassDesc, ClassDesc.of("", "ClassDescTest"));
|
||||
assertEquals(thisClassDesc, ClassDesc.of("ClassDescTest"));
|
||||
@ -261,6 +265,17 @@ public class ClassDescTest extends SymbolicDescTest {
|
||||
}
|
||||
}
|
||||
|
||||
List<String> badInternalNames = List.of("I;", "[]", "[Ljava/lang/String;",
|
||||
"Ljava.lang.String;", "java.lang.String");
|
||||
for (String d : badInternalNames) {
|
||||
try {
|
||||
ClassDesc constant = ClassDesc.ofInternalName(d);
|
||||
fail(d);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
|
||||
for (Primitives p : Primitives.values()) {
|
||||
testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any");
|
||||
testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any", "other");
|
||||
|
Loading…
Reference in New Issue
Block a user