如何在Java源文件中获取给定行号的周围方法 [英] How to get surrounding method in Java source file for a given line number
问题描述
我有一个Java源文件的行号,并希望以编程方式获取该行号的搜索方法。
I have a line number of a Java source file and want to get the sourounding method for that line number programatically.
我查看了 ANTLR 对我没什么帮助。
I looked into ANTLR which didn't help me much.
Janino( http://www.janino.net )看起来很有希望,我会扫描并解析(如果需要编译)代码。然后我可以使用 JDI 和
Janino (http://www.janino.net) seems promising, I would scan and parse (and if necessary compile) the code. Then I could use JDI and
ReferenceType.locationsOfLine(int lineNumber)
我仍然不知道如何使用JDI这样做,并且没有找到这个方向的教程。
Still I don't know how to use JDI for doing this and didn't find a tutorial that goes anywhere in this direction.
也许还有其他一些我完全失踪的方式。
Maybe there is some other way that I am completely missing.
推荐答案
如果你使用的是Java 6,如果你不介意使用Sun的API,那么你可以使用 javac API 。您需要将 tools.jar
添加到类路径中。
If you're using Java 6, and if you don't mind using Sun's APIs, then you can use the javac API. You'll need to add tools.jar
to your classpath.
import java.io.IOException;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.LineMap;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreeScanner;
import com.sun.source.util.Trees;
public class MethodFinder {
public static void main(String[] args) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnosticsCollector = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticsCollector, null, null);
Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects("path/to/Source.java");
CompilationTask task = compiler.getTask(null, fileManager, diagnosticsCollector, null, null, fileObjects);
// Here we switch to Sun-specific APIs
JavacTask javacTask = (JavacTask) task;
SourcePositions sourcePositions = Trees.instance(javacTask).getSourcePositions();
Iterable<? extends CompilationUnitTree> parseResult = null;
try {
parseResult = javacTask.parse();
} catch (IOException e) {
// Parsing failed
e.printStackTrace();
System.exit(0);
}
for (CompilationUnitTree compilationUnitTree : parseResult) {
compilationUnitTree.accept(new MethodLineLogger(compilationUnitTree, sourcePositions), null);
}
}
private static class MethodLineLogger extends TreeScanner<Void, Void> {
private final CompilationUnitTree compilationUnitTree;
private final SourcePositions sourcePositions;
private final LineMap lineMap;
private MethodLineLogger(CompilationUnitTree compilationUnitTree, SourcePositions sourcePositions) {
this.compilationUnitTree = compilationUnitTree;
this.sourcePositions = sourcePositions;
this.lineMap = compilationUnitTree.getLineMap();
}
@Override
public Void visitMethod(MethodTree arg0, Void arg1) {
long startPosition = sourcePositions.getStartPosition(compilationUnitTree, arg0);
long startLine = lineMap.getLineNumber(startPosition);
long endPosition = sourcePositions.getEndPosition(compilationUnitTree, arg0);
long endLine = lineMap.getLineNumber(endPosition);
// Voila!
System.out.println("Found method " + arg0.getName() + " from line " + startLine + " to line " + endLine + ".");
return super.visitMethod(arg0, arg1);
}
}
}
这篇关于如何在Java源文件中获取给定行号的周围方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!