mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8278863: Add method ClassDesc::ofInternalName
Reviewed-by: jvernee
This commit is contained in:
parent
4020ed53dd
commit
0fa7d9e8cd
3 changed files with 61 additions and 0 deletions
|
@ -72,12 +72,39 @@ public sealed interface ClassDesc
|
||||||
* @throws NullPointerException if the argument is {@code null}
|
* @throws NullPointerException if the argument is {@code null}
|
||||||
* @throws IllegalArgumentException if the name string is not in the
|
* @throws IllegalArgumentException if the name string is not in the
|
||||||
* correct format
|
* correct format
|
||||||
|
* @see ClassDesc#ofDescriptor(String)
|
||||||
|
* @see ClassDesc#ofInternalName(String)
|
||||||
*/
|
*/
|
||||||
static ClassDesc of(String name) {
|
static ClassDesc of(String name) {
|
||||||
ConstantUtils.validateBinaryClassName(requireNonNull(name));
|
ConstantUtils.validateBinaryClassName(requireNonNull(name));
|
||||||
return ClassDesc.ofDescriptor("L" + binaryToInternal(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,
|
* Returns a {@linkplain ClassDesc} for a class or interface type,
|
||||||
* given a package name and the unqualified (simple) name for the
|
* given a package name and the unqualified (simple) name for the
|
||||||
|
@ -125,6 +152,8 @@ public sealed interface ClassDesc
|
||||||
* correct format
|
* correct format
|
||||||
* @jvms 4.3.2 Field Descriptors
|
* @jvms 4.3.2 Field Descriptors
|
||||||
* @jvms 4.4.1 The CONSTANT_Class_info Structure
|
* @jvms 4.4.1 The CONSTANT_Class_info Structure
|
||||||
|
* @see ClassDesc#of(String)
|
||||||
|
* @see ClassDesc#ofInternalName(String)
|
||||||
*/
|
*/
|
||||||
static ClassDesc ofDescriptor(String descriptor) {
|
static ClassDesc ofDescriptor(String descriptor) {
|
||||||
requireNonNull(descriptor);
|
requireNonNull(descriptor);
|
||||||
|
|
|
@ -58,6 +58,23 @@ class ConstantUtils {
|
||||||
return name;
|
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
|
* Validates a member name
|
||||||
*
|
*
|
||||||
|
|
|
@ -133,6 +133,7 @@ public class ClassDescTest extends SymbolicDescTest {
|
||||||
public void testSimpleClassDesc() throws ReflectiveOperationException {
|
public void testSimpleClassDesc() throws ReflectiveOperationException {
|
||||||
|
|
||||||
List<ClassDesc> stringClassDescs = Arrays.asList(ClassDesc.ofDescriptor("Ljava/lang/String;"),
|
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"),
|
ClassDesc.of("java.lang.String"),
|
||||||
ClassDesc.of("java.lang.String").arrayType().componentType(),
|
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.lang.String").arrayType(), String[].class);
|
||||||
testClassDesc(ClassDesc.of("java.util.Map").nested("Entry"), Map.Entry.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;");
|
ClassDesc thisClassDesc = ClassDesc.ofDescriptor("LClassDescTest;");
|
||||||
assertEquals(thisClassDesc, ClassDesc.of("", "ClassDescTest"));
|
assertEquals(thisClassDesc, ClassDesc.of("", "ClassDescTest"));
|
||||||
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()) {
|
for (Primitives p : Primitives.values()) {
|
||||||
testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any");
|
testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any");
|
||||||
testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any", "other");
|
testBadNestedClasses(ClassDesc.ofDescriptor(p.descriptor), "any", "other");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue