8306698: Add overloads to MethodTypeDesc::of

Reviewed-by: mchung
This commit is contained in:
Chen Liang 2023-05-23 21:26:25 +00:00 committed by Mandy Chung
parent 6b27dad76e
commit 8ffa264cf0
3 changed files with 53 additions and 38 deletions
src/java.base/share/classes/java/lang/constant
test/jdk/java/lang/constant

@ -36,6 +36,7 @@ import static java.util.Objects.requireNonNull;
class ConstantUtils {
/** an empty constant descriptor */
public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0];
static final ClassDesc[] EMPTY_CLASSDESC = new ClassDesc[0];
static final Constable[] EMPTY_CONSTABLE = new Constable[0];
static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;

@ -55,6 +55,34 @@ public sealed interface MethodTypeDesc
return MethodTypeDescImpl.ofDescriptor(descriptor);
}
/**
* {@return a {@linkplain MethodTypeDesc} with the given return type and no
* parameter types}
*
* @param returnDesc a {@linkplain ClassDesc} describing the return type
* @throws NullPointerException if {@code returnDesc} is {@code null}
* @since 21
*/
static MethodTypeDesc of(ClassDesc returnDesc) {
return new MethodTypeDescImpl(returnDesc, ConstantUtils.EMPTY_CLASSDESC);
}
/**
* {@return a {@linkplain MethodTypeDesc} given the return type and a list of
* parameter types}
*
* @param returnDesc a {@linkplain ClassDesc} describing the return type
* @param paramDescs a {@linkplain List} of {@linkplain ClassDesc}s
* describing the parameter types
* @throws NullPointerException if any argument or its contents are {@code null}
* @throws IllegalArgumentException if any element of {@code paramDescs} is a
* {@link ClassDesc} for {@code void}
* @since 21
*/
static MethodTypeDesc of(ClassDesc returnDesc, List<ClassDesc> paramDescs) {
return of(returnDesc, paramDescs.toArray(ConstantUtils.EMPTY_CLASSDESC));
}
/**
* Returns a {@linkplain MethodTypeDesc} given the return type and parameter
* types.

@ -25,6 +25,7 @@ import java.lang.invoke.MethodType;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
@ -36,6 +37,7 @@ import static java.lang.constant.ConstantDescs.CD_void;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.fail;
/**
@ -52,6 +54,9 @@ public class MethodTypeDescTest extends SymbolicDescTest {
// Tests accessors (rType, pType, pCount, pList, pArray, descriptorString),
// factories (ofDescriptor, of), equals
if (r.parameterCount() == 0) {
assertEquals(r, MethodTypeDesc.of(r.returnType()));
}
assertEquals(r, MethodTypeDesc.ofDescriptor(r.descriptorString()));
assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterArray()));
assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterList().toArray(new ClassDesc[0])));
@ -59,6 +64,12 @@ public class MethodTypeDescTest extends SymbolicDescTest {
assertEquals(r, MethodTypeDesc.of(r.returnType(), IntStream.range(0, r.parameterCount())
.mapToObj(r::parameterType)
.toArray(ClassDesc[]::new)));
assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterList()));
assertEquals(r, MethodTypeDesc.of(r.returnType(), List.copyOf(r.parameterList())));
assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterList().stream().toList()));
assertEquals(r, MethodTypeDesc.of(r.returnType(), IntStream.range(0, r.parameterCount())
.mapToObj(r::parameterType)
.toList()));
}
private void testMethodTypeDesc(MethodTypeDesc r, MethodType mt) throws ReflectiveOperationException {
@ -255,54 +266,29 @@ public class MethodTypeDescTest extends SymbolicDescTest {
}
public void testBadMethodTypeRefs() {
// ofDescriptor
List<String> badDescriptors = List.of("()II", "()I;", "(I;)", "(I)", "()L", "(V)V",
"(java.lang.String)V", "()[]", "(Ljava/lang/String)V",
"(Ljava.lang.String;)V", "(java/lang/String)V");
for (String d : badDescriptors) {
try {
MethodTypeDesc r = MethodTypeDesc.ofDescriptor(d);
fail(d);
}
catch (IllegalArgumentException e) {
// good
}
assertThrows(IllegalArgumentException.class, () -> MethodTypeDesc.ofDescriptor(d));
}
assertThrows(NullPointerException.class, () -> MethodTypeDesc.ofDescriptor(null));
// try with null argument
try {
MethodTypeDesc r = MethodTypeDesc.ofDescriptor(null);
fail("should fail with NPE");
} catch (NullPointerException ex) {
// good
}
// of(ClassDesc)
assertThrows(NullPointerException.class, () -> MethodTypeDesc.of(null));
// of(ClassDesc, ClassDesc...)
assertThrows(NullPointerException.class, () -> MethodTypeDesc.of(CD_int, (ClassDesc[]) null));
assertThrows(NullPointerException.class, () -> MethodTypeDesc.of(CD_int, new ClassDesc[] {null}));
// try with void arguments, this will stress another code path in particular
// ConstantMethodTypeDesc::init
try {
MethodTypeDesc r = MethodTypeDesc.of(CD_int, CD_void);
fail("can't reach here");
}
catch (IllegalArgumentException e) {
// good
}
assertThrows(IllegalArgumentException.class, () -> MethodTypeDesc.of(CD_int, CD_void));
try {
MethodTypeDesc r = MethodTypeDesc.of(CD_int, null);
fail("ClassDesc array should not be null");
}
catch (NullPointerException e) {
// good
}
try {
ClassDesc[] paramDescs = new ClassDesc[1];
paramDescs[0] = null;
MethodTypeDesc r = MethodTypeDesc.of(CD_int, paramDescs);
fail("ClassDesc should not be null");
}
catch (NullPointerException e) {
// good
}
// of(ClassDesc, List<ClassDesc>)
assertThrows(NullPointerException.class, () -> MethodTypeDesc.of(CD_int, (List<ClassDesc>) null));
assertThrows(NullPointerException.class, () -> MethodTypeDesc.of(CD_int, Collections.singletonList(null)));
assertThrows(IllegalArgumentException.class, () -> MethodTypeDesc.of(CD_int, List.of(CD_void)));
}
}