Example usage for org.objectweb.asm TypePath ARRAY_ELEMENT

List of usage examples for org.objectweb.asm TypePath ARRAY_ELEMENT

Introduction

In this page you can find the example usage for org.objectweb.asm TypePath ARRAY_ELEMENT.

Prototype

int ARRAY_ELEMENT

To view the source code for org.objectweb.asm TypePath ARRAY_ELEMENT.

Click Source Link

Document

A type path step that steps into the element type of an array type.

Usage

From source file:org.decojer.cavaj.readers.asm.ReadUtils.java

License:Open Source License

@Nonnull
private static T annotatePart(@Nonnull final T t, @Nonnull final A a, @Nullable final TypePath typePath,
        final int index) {
    if (typePath == null) {
        return DU.getAnnotatedT(t, a);
    }/* w ww  .  j av a2 s .c o  m*/
    final int typePathLength = typePath.getLength();
    if (typePathLength == index) {
        return DU.getAnnotatedT(t, a);
    }
    assert index < typePathLength : "type path exceeded for: " + t;

    // JVMS: If the value of the type_path_kind item is 0, 1, or 2, then the value of the
    // type_argument_index item is 0.
    // If the value of the type_path_kind item is 3, then the value of
    // the type_argument_index item specifies which type argument of a
    // parameterized type is annotated, where 0 indicates the first type argument
    // of a parameterized type.

    final int step = typePath.getStep(index);
    final int arg = typePath.getStepArgument(index);

    // that we are here means, that we have to zoom into the modified type...so we can
    // unwrap the annotation type here
    switch (step) {
    case TypePath.ARRAY_ELEMENT: {
        assert arg == 0 : arg;

        // @C T @A [] @B [] f;
        // @A applies to the array type T[][], @B applies to its component type T[], and
        // @C applies to the final element type T.
        // -> Bytecode: T[][] and @A (NEW / VAR), @B (ARRAY), @C (ARRAY, ARRAY)

        // hence: type path step "ARRAY" can be interpreted as: component type,
        // @A applies to full type: Anno(T[][], @A) -> T @A[][]
        // Anno(Array(Anno(Array(Anno(T, @C), @B)), @A))

        final T componentT = t.getComponentT();
        if (componentT == null) {
            log.warn("Not enough array components in '" + t + "' for type annotation path!");
            break;
        }
        t.setComponentT(annotateT(componentT, a, typePath, index + 1));
        return t;
    }
    case TypePath.INNER_TYPE: {
        assert false : "type path step argument for INNER must be handled in calling function annotate()";
    }
    case TypePath.TYPE_ARGUMENT: {
        final T[] typeArgs = t.getTypeArgs();
        if (typeArgs.length <= arg) {
            log.warn("Not enough type arguments in '" + t + "' for type annotation path with argument '" + arg
                    + "'!");
            break;
        }
        final T typeArg = typeArgs[arg];
        assert typeArg != null;
        typeArgs[arg] = annotateT(typeArg, a, typePath, index + 1);
        break;
    }
    case TypePath.WILDCARD_BOUND: {
        assert arg == 0 : arg;

        final T boundT = t.getBoundT();
        if (boundT == null) {
            log.warn("No wildcard bound in '" + t + "' for type annotation path!");
            break;
        }
        t.setBoundT(annotateT(boundT, a, typePath, index + 1));
        break;
    }
    default:
        log.warn("Unknown step '0x" + Integer.toHexString(step) + "' in '" + t
                + "' for type annotation path with argument '" + arg + "'!");
    }
    return t;
}