Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用java ASM确定方法的行号?_Java_Bytecode_Java Bytecode Asm_Line Numbers - Fatal编程技术网

如何使用java ASM确定方法的行号?

如何使用java ASM确定方法的行号?,java,bytecode,java-bytecode-asm,line-numbers,Java,Bytecode,Java Bytecode Asm,Line Numbers,我需要使用ObjectWebASM库确定类中特定方法的行号方法声明的行号或方法正文中的第一行同样被认为是正确答案(示例中为6或7) 例子: 我尝试使用MethodVisitor的visitLineNumber方法,但它只访问第一个可执行行(示例中的第9行)。 我在JavaAssist库()上找到了这个问题的解决方案但是有没有办法用ASM解决这个问题 编辑: 下面的代码段给出了相同的结果,第9行而不是第6行或第7行 public static int getLineNumber(String pa

我需要使用ObjectWebASM库确定类中特定方法的行号
方法声明的行号或方法正文中的第一行同样被认为是正确答案(示例中为6或7)

例子: 我尝试使用MethodVisitor的visitLineNumber方法,但它只访问第一个可执行行(示例中的第9行)。
我在JavaAssist库()上找到了这个问题的解决方案
但是有没有办法用ASM解决这个问题

编辑: 下面的代码段给出了相同的结果,第9行而不是第6行或第7行

public static int getLineNumber(String path) throws IOException {
        final File f = new File(path);
        try (FileInputStream fis = new FileInputStream(f)) {
            ClassReader reader = new ClassReader(fis);
            ClassNode clNode = new ClassNode(Opcodes.ASM5);
            reader.accept(clNode, Opcodes.ASM5);
            for (MethodNode mNode : (List<MethodNode>) clNode.methods) {
                if (mNode.name.equals("bar")) {
                    ListIterator<AbstractInsnNode> it = mNode.instructions.iterator();
                    while (it.hasNext()) {
                        AbstractInsnNode inNode = it.next();
                        if (inNode instanceof LineNumberNode) {
                            return ((LineNumberNode) inNode).line;
                        }
                    }
                }
            }
        }
        return -1;
    }
public static int getLineNumber(字符串路径)引发IOException{
最终文件f=新文件(路径);
try(FileInputStream fis=newfileinputstream(f)){
ClassReader=新的ClassReader(fis);
ClassNode clNode=新的ClassNode(操作码.ASM5);
accept(clNode,操作码.ASM5);
for(MethodNode mNode:(列表)clNode.methods){
if(mNode.name.equals(“bar”)){
ListIterator it=mNode.instructions.iterator();
while(it.hasNext()){
AbstractInNode inNode=it.next();
if(LineNumberNode的inNode实例){
返回((LineNumberNode)inNode).line;
}
}
}
}
}
返回-1;
}
公共静态行号节点查找行号指令(InsnList
insnList,AbstractInsnNode insnNode){
Validate.notNull(insnList);
Validate.notNull(insnNode);
int idx=insnList.indexOf(insnNode);
Validate.isTrue(idx!=-1);
//在方法中获取标签和insnNode的索引
ListIterator insnIt=insnList.iterator(idx);
while(insnIt.hasPrevious()){
AbstractInsnNode节点=insnIt.previous();
if(LineNumberNode的节点实例){
返回(LineNumberNode)节点;
}
}
返回null;

}

任何字节码处理库提供的行号都基于将方法的可执行指令映射到行号的方法。因此,在类文件中找不到不会生成可执行字节码的源代码行是一个基本限制


有时它甚至取决于编译器,跨越多行的构造被分配到哪个源代码行。

谢谢您的回答。正如@Holger所说,这个问题无法解决,但你们给出了一个有用的例子。
public static int getLineNumber(String path) throws IOException {
        final File f = new File(path);
        try (FileInputStream fis = new FileInputStream(f)) {
            ClassReader reader = new ClassReader(fis);
            ClassNode clNode = new ClassNode(Opcodes.ASM5);
            reader.accept(clNode, Opcodes.ASM5);
            for (MethodNode mNode : (List<MethodNode>) clNode.methods) {
                if (mNode.name.equals("bar")) {
                    ListIterator<AbstractInsnNode> it = mNode.instructions.iterator();
                    while (it.hasNext()) {
                        AbstractInsnNode inNode = it.next();
                        if (inNode instanceof LineNumberNode) {
                            return ((LineNumberNode) inNode).line;
                        }
                    }
                }
            }
        }
        return -1;
    }
public static LineNumberNode findLineNumberForInstruction(InsnList 
insnList, AbstractInsnNode insnNode) {
    Validate.notNull(insnList);
    Validate.notNull(insnNode);

    int idx = insnList.indexOf(insnNode);
    Validate.isTrue(idx != -1);

    // Get index of labels and insnNode within method
    ListIterator<AbstractInsnNode> insnIt = insnList.iterator(idx);
    while (insnIt.hasPrevious()) {
        AbstractInsnNode node = insnIt.previous();

        if (node instanceof LineNumberNode) {
            return (LineNumberNode) node;
        }
    }

    return null;