java variables locales - ¿Cómo puedo obtener un nombre de variable o escribe utilizando su índice

StackOverflow https://stackoverflow.com/questions/4324321

Pregunta

Estoy usando la biblioteca ASM instrumentación. Usando visitVarInsn consigo el índice de una variable local. Quiero utilizar ese índice y recibir información más útil como el nombre de la variable y el tipo. ¿tiene alguna idea de cómo? gracias.

¿Fue útil?

Otros consejos

Estoy utilizando el código de abajo:

    private LocalVariableNode getLocalVariableNode(VarInsnNode varInsnNode, MethodNode methodNode) {
        int varIdx = varInsnNode.var;
        int instrIdx = getInstrIndex(varInsnNode);
        List<?> localVariables = methodNode.localVariables;
        for (int idx = 0; idx < localVariables.size(); idx++) {
            LocalVariableNode localVariableNode = (LocalVariableNode) localVariables.get(idx);
            if (localVariableNode.index == varIdx) {
                int scopeEndInstrIndex = getInstrIndex(localVariableNode.end);
                if (scopeEndInstrIndex >= instrIdx) {
                    // still valid for current line
                    return localVariableNode;
                }
            }
        }
        throw new RuntimeException("Variable with index " + varIdx + " and scope end >= " + instrIdx
                + " not found for method " + methodNode.name + "!");
    }

El problema general es que el índice de la variable local puede ser reutilizado. Así que hay que asegurarse de que está recibiendo el LocalVariableNode correcto para un índice dado. Para ello, es necesario asegurarse de que la variable dada es todavía válida en la posición de código en la que se utiliza. El problema es que no se puede utilizar números de línea, porque

  1. la posición inicial es la siguiente línea de código después se definió la variable. Ya que las líneas vacías y comentarios son ignorados, que puede ser cualquier línea siguiente. Pero ya que el código podría volver a utilizar una variable existente, esto también podría ser cualquier línea antes de la línea actual.

  2. la posición final puede ser antes de la posición inicial de la línea a gota (por ejemplo en un bucle).

  3. el código podría haber sido compilado sin información de línea.

Así que hay que utilizar el índice de instrucciones, que siempre es correcta. Pero es una información interna en AbstractInsnNode que no se puede acceder desde el exterior. Para evitar este problema, yo uso el siguiente código, que, obviamente, se rompe la encapsulación y no es recomendable para una serie de razones. Si se te ocurre nada mejor, que me haga saber! Mientras tanto, esta obra:

    private int getInstrIndex(AbstractInsnNode insnNode) {
        try {
            Field indexField = AbstractInsnNode.class.getDeclaredField("index");
            indexField.setAccessible(true);
            Object indexValue = indexField.get(insnNode);
            return ((Integer) indexValue).intValue();
        } catch (Exception exc) {
            throw new RuntimeException(exc);
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top