Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8278863: Add method ClassDesc::ofInternalName #9201

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/java.base/share/classes/java/lang/constant/ClassDesc.java
Expand Up @@ -78,6 +78,26 @@ static ClassDesc of(String 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"}.
* (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
*/
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
Expand Down
17 changes: 17 additions & 0 deletions src/java.base/share/classes/java/lang/constant/ConstantUtils.java
Expand Up @@ -58,6 +58,23 @@ static String validateBinaryClassName(String 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
*
Expand Down
15 changes: 15 additions & 0 deletions test/jdk/java/lang/constant/ClassDescTest.java
Expand Up @@ -133,6 +133,7 @@ public void testPrimitiveClassDesc() throws ReflectiveOperationException {
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(),
Expand All @@ -149,6 +150,9 @@ public void testSimpleClassDesc() throws ReflectiveOperationException {
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"));
Expand Down Expand Up @@ -261,6 +265,17 @@ public void testBadClassDescs() {
}
}

List<String> badInternalNames = List.of("I;", "[]",
asotona marked this conversation as resolved.
Show resolved Hide resolved
"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");
Expand Down