Example usage for org.objectweb.asm.tree InsnList size

List of usage examples for org.objectweb.asm.tree InsnList size

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList size.

Prototype

int size

To view the source code for org.objectweb.asm.tree InsnList size.

Click Source Link

Document

The number of instructions in this list.

Usage

From source file:works.cirno.mocha.parameter.name.ASMParameterAnalyzer.java

License:Open Source License

@Override
@SuppressWarnings("unchecked")
public Parameter[] getParameters(InvokeTarget target, Parameter[] parameters) {
    if (!enabled) {
        return parameters;
    }/*  w w  w  .j ava2s  .co m*/
    Class<?> controllerClass = target.getControllerClass();
    Method method = target.getMethod();
    String methodName = method.getName();

    Class<?>[] parameterTypes = method.getParameterTypes();
    int parameterCount = parameterTypes.length;

    // /////////Resolve parameter names by asm
    {
        if (log.isDebugEnabled()) {
            log.debug("Analyzing method {}.{}", controllerClass.getName(), method.getName());
        }
        ClassNode node = classNodeCache.get(controllerClass);
        if (node == null) {
            String name = controllerClass.getName();
            {
                int idx = name.lastIndexOf('.');
                if (idx > 0) {
                    name = name.substring(idx + 1);
                }
            }

            try (InputStream is = controllerClass.getResourceAsStream(name + ".class")) {
                if (is == null) {
                    throw new FileNotFoundException(name + ".class");
                }
                ClassReader cr = new ClassReader(is);
                node = new ClassNode();
                cr.accept(node, ClassReader.SKIP_FRAMES);
                classNodeCache.put(controllerClass, node);
            } catch (IOException e) {
                log.warn("Can't read bytecode of class " + name);
                return null;
            }
        }

        if (parameters == null) {
            parameters = new Parameter[parameterCount];
        } else if (parameters.length != parameterCount) {
            throw new IllegalArgumentException(
                    "Input parameters' length is different than parameters of target");
        }

        boolean methodNodeGot = false;
        for (MethodNode m : (List<MethodNode>) node.methods) {
            if (methodName.equals(m.name)) {
                String[] names = new String[parameterCount];
                // do it
                {
                    IdentityHashMap<LabelNode, Integer> labelPosMap = new IdentityHashMap<>();
                    int pos = 0;
                    InsnList il = m.instructions;
                    for (int i = 0, max = il.size(); i < max; i++) {
                        AbstractInsnNode ain = il.get(i);
                        if (ain.getType() == AbstractInsnNode.LABEL) {
                            LabelNode label = (LabelNode) ain;
                            labelPosMap.put(label, pos++);
                        }
                    }
                    int[] poses = new int[parameterCount];
                    for (int i = 0; i < parameterCount; i++) {
                        poses[i] = Integer.MAX_VALUE;
                    }

                    for (LocalVariableNode lvn : (List<LocalVariableNode>) m.localVariables) {
                        if (lvn.index > 0 && lvn.index <= parameterCount) {
                            int idx = lvn.index - 1;
                            int startPos = labelPosMap.get(lvn.start);
                            if (poses[idx] > startPos) {
                                poses[idx] = startPos;
                                names[idx] = lvn.name;
                            }
                        }
                    }
                }

                if (log.isDebugEnabled()) {
                    log.debug("Method {}.{} has parameter: {}", controllerClass.getName(), method.getName(),
                            Arrays.toString(names));
                }
                for (int i = 0; i < parameterCount; i++) {
                    if (parameters[i] == null || parameters[i].getName() == null) {
                        parameters[i] = new Parameter(names[i], parameterTypes[i]);
                    }
                }

                methodNodeGot = true;
                break;
            }
        }
        if (!methodNodeGot) {
            throw new IllegalStateException("Can't get method " + method.getName() + " from ASM");
        }
        return parameters;
    }
}