use of java.lang.constant.MethodHandleDesc in project openj9 by eclipse.
the class StructuralComparator method describeConstable.
/*[IF JAVA_SPEC_VERSION >= 12]*/
/**
* Returns the nominal descriptor of this MethodHandle instance, or an empty Optional
* if construction is not possible.
*
* @return Optional with a nominal descriptor of MethodHandle instance
*/
public Optional<MethodHandleDesc> describeConstable() {
try {
DirectMethodHandleDesc.Kind handleKind;
/* Define handle as a crackable type. If its not possible to do so this method should fail */
MethodHandleInfo handleInfo = Lookup.IMPL_LOOKUP.revealDirect(this);
switch(handleInfo.getReferenceKind()) {
case MethodHandleInfo.REF_getField:
handleKind = DirectMethodHandleDesc.Kind.GETTER;
break;
case MethodHandleInfo.REF_getStatic:
handleKind = DirectMethodHandleDesc.Kind.STATIC_GETTER;
break;
case MethodHandleInfo.REF_putField:
handleKind = DirectMethodHandleDesc.Kind.SETTER;
break;
case MethodHandleInfo.REF_putStatic:
handleKind = DirectMethodHandleDesc.Kind.STATIC_SETTER;
break;
case MethodHandleInfo.REF_invokeVirtual:
handleKind = DirectMethodHandleDesc.Kind.VIRTUAL;
break;
case MethodHandleInfo.REF_invokeStatic:
if (handleInfo.getDeclaringClass().isInterface()) {
handleKind = DirectMethodHandleDesc.Kind.INTERFACE_STATIC;
} else {
handleKind = DirectMethodHandleDesc.Kind.STATIC;
}
break;
case MethodHandleInfo.REF_invokeSpecial:
if (handleInfo.getDeclaringClass().isInterface()) {
handleKind = DirectMethodHandleDesc.Kind.INTERFACE_SPECIAL;
} else {
handleKind = DirectMethodHandleDesc.Kind.SPECIAL;
}
break;
case MethodHandleInfo.REF_newInvokeSpecial:
handleKind = DirectMethodHandleDesc.Kind.CONSTRUCTOR;
break;
case MethodHandleInfo.REF_invokeInterface:
handleKind = DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL;
break;
default:
/* fail */
return Optional.empty();
}
/* create descriptor for the declaring class */
ClassDesc declaringDesc = handleInfo.getDeclaringClass().describeConstable().orElseThrow();
/* create handle descriptor */
MethodHandleDesc handleDesc;
switch(handleInfo.getReferenceKind()) {
/* field types */
case MethodHandleInfo.REF_getField:
case MethodHandleInfo.REF_getStatic:
case MethodHandleInfo.REF_putField:
case MethodHandleInfo.REF_putStatic:
ClassDesc fieldType = ((FieldHandle) this).fieldClass.describeConstable().orElseThrow();
handleDesc = MethodHandleDesc.ofField(handleKind, declaringDesc, handleInfo.getName(), fieldType);
break;
/* method types */
case MethodHandleInfo.REF_invokeVirtual:
case MethodHandleInfo.REF_invokeStatic:
case MethodHandleInfo.REF_invokeSpecial:
case MethodHandleInfo.REF_invokeInterface:
MethodTypeDesc lookupType = handleInfo.getMethodType().describeConstable().orElseThrow();
handleDesc = MethodHandleDesc.ofMethod(handleKind, declaringDesc, handleInfo.getName(), lookupType);
break;
/* constructor types */
case MethodHandleInfo.REF_newInvokeSpecial:
/* create list of descriptors for constructor parameters */
Class<?>[] handleParams = handleInfo.getMethodType().parameterArray();
int paramCount = handleParams.length;
ClassDesc[] paramDescs = new ClassDesc[paramCount];
for (int i = 0; i < paramCount; i++) {
paramDescs[i] = handleParams[i].describeConstable().orElseThrow();
}
handleDesc = MethodHandleDesc.ofConstructor(declaringDesc, paramDescs);
break;
default:
/* fail */
return Optional.empty();
}
return Optional.ofNullable(handleDesc);
} catch (IllegalArgumentException | SecurityException | NoSuchElementException e) {
/* fail */
return Optional.empty();
}
}
use of java.lang.constant.MethodHandleDesc in project openj9 by eclipse.
the class Test_MethodHandle method testMethodDescribeConstableGeneralSub.
private void testMethodDescribeConstableGeneralSub(String testName, MethodHandle handle, MethodHandles.Lookup resolveLookup) throws Throwable {
MethodHandleDesc handleDesc = handle.describeConstable().orElseThrow();
/* verify that descriptor can be resolved. If not ReflectiveOperationException will be thrown. */
MethodHandle resolvedHandle = (MethodHandle) handleDesc.resolveConstantDesc(resolveLookup);
/* verify that resolved MethodType is the same as original */
MethodHandleInfo oInfo = MethodHandles.lookup().revealDirect(handle);
MethodHandleInfo rInfo = MethodHandles.lookup().revealDirect(resolvedHandle);
logger.debug(testName + ": Descriptor of original MethodHandle " + oInfo.getMethodType().descriptorString() + " descriptor of MethodHandleDesc is: " + rInfo.getMethodType().descriptorString());
Assert.assertTrue(oInfo.getMethodType().equals(rInfo.getMethodType()));
Assert.assertTrue(oInfo.getDeclaringClass().equals(rInfo.getDeclaringClass()));
Assert.assertTrue(oInfo.getName().equals(rInfo.getName()));
Assert.assertEquals(oInfo.getModifiers(), rInfo.getModifiers());
Assert.assertEquals(oInfo.getReferenceKind(), rInfo.getReferenceKind());
}
Aggregations