Search in sources :

Example 1 with MethodHandleDesc

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();
    }
}
Also used : Kind(java.lang.constant.DirectMethodHandleDesc.Kind) MethodTypeDesc(java.lang.constant.MethodTypeDesc) DirectMethodHandleDesc(java.lang.constant.DirectMethodHandleDesc) MethodHandleDesc(java.lang.constant.MethodHandleDesc) DirectMethodHandleDesc(java.lang.constant.DirectMethodHandleDesc) NoSuchElementException(java.util.NoSuchElementException) ClassDesc(java.lang.constant.ClassDesc)

Example 2 with MethodHandleDesc

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());
}
Also used : MethodHandleDesc(java.lang.constant.MethodHandleDesc) MethodHandleInfo(java.lang.invoke.MethodHandleInfo) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

MethodHandleDesc (java.lang.constant.MethodHandleDesc)2 ClassDesc (java.lang.constant.ClassDesc)1 DirectMethodHandleDesc (java.lang.constant.DirectMethodHandleDesc)1 Kind (java.lang.constant.DirectMethodHandleDesc.Kind)1 MethodTypeDesc (java.lang.constant.MethodTypeDesc)1 MethodHandle (java.lang.invoke.MethodHandle)1 MethodHandleInfo (java.lang.invoke.MethodHandleInfo)1 NoSuchElementException (java.util.NoSuchElementException)1