[英]Learning Java Compiler APIs,why does trees.getElement(treepath) return null?
I'm trying to parse a java file with Java Compiler APIs. 我正在尝试使用Java编译器API解析Java文件。
The documents are very poor. 文件很差。 After hours of digging I still cannot get the
Trees#getElement
work for me. 经过数小时的挖掘,我仍然无法为我使用
Trees#getElement
。 Here's my code: 这是我的代码:
import com.sun.source.tree.*;
import com.sun.source.util.*;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class CodeAnalyzerTreeVisitor extends TreePathScanner<Object, Trees> {
@Override
public Object visitClass(ClassTree classTree, Trees trees) {
System.out.println("className " + classTree.getSimpleName());
//prints name of class
TreePath path = getCurrentPath();
printLocationAndSource(trees, path, classTree);
//prints the original source code
while (path != null) { System.out.println("treepath"); System.out.println(trees.getElement(path)); path = path.getParentPath(); } //it prints several nulls here //why?
return super.visitClass(classTree, trees);
}
public static void printLocationAndSource(Trees trees,
TreePath path, Tree tree) {
SourcePositions sourcePosition = trees.getSourcePositions();
long startPosition = sourcePosition.
getStartPosition(path.getCompilationUnit(), tree);
long endPosition = sourcePosition.
getEndPosition(path.getCompilationUnit(), tree);
JavaFileObject file = path.getCompilationUnit().getSourceFile();
CharBuffer sourceContent = null;
try {
sourceContent = CharBuffer.wrap(file.getCharContent(true).toString().toCharArray());
} catch (IOException e) {
e.printStackTrace();
}
CharBuffer relatedSource = null;
if (sourceContent != null) {
relatedSource = sourceContent.subSequence((int) startPosition, (int) endPosition);
}
System.out.println("start: " + startPosition + " end: " + endPosition);
// System.out.println("source: "+relatedSource);
System.out.println();
}
}
public class JavaParser {
private static final JavaCompiler javac
= ToolProvider.getSystemJavaCompiler();
private static final String filePath = "/home/pinyin/Source/hadoop-common/hadoop-yarn-project/hadoop-ya" +
"rn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/ya" +
"rn/server/resourcemanager/ResourceManager.java";
public static void main(String[] args) throws IOException {
StandardJavaFileManager jfm = javac.getStandardFileManager(null, null, null);
Iterable<? extends javax.tools.JavaFileObject> javaFileObjects = jfm.getJavaFileObjects(filePath);
String[] sourcePathParam = {
"-sourcepath",
"/home/pinyin/Source/hadoop-common/hadoop-yarn-project/hadoop-yarn/" +
"hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/"
};
List<String> params = new ArrayList<String>();
params.addAll(Arrays.asList(sourcePathParam));
JavacTask task = (JavacTask) javac.getTask(null, jfm, null, params, null, javaFileObjects);
Iterable<? extends CompilationUnitTree> asts = task.parse();
Trees trees = Trees.instance(task);
for (CompilationUnitTree ast : asts) {
new CodeAnalyzerTreeVisitor().scan(ast, trees);
}
}
}
The lines about params
and -sourcepath
are added because I thought the compiler is trying to find the source file in the wrong places. 添加了有关
params
和-sourcepath
的行,因为我认为编译器试图在错误的位置找到源文件。 They didn't work. 他们没有工作。
I'm still trying to understand how the Trees
, javac and related JSRs work together, are there any recommended documents for beginners? 我仍在尝试了解
Trees
,javac和相关的JSR如何一起工作,是否有针对初学者的推荐文档? Thanks for your help. 谢谢你的帮助。
edit: The java file I'm trying to analyze is: https://github.com/apache/hadoop-common/blob/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java 编辑:我想分析的Java文件是: https : //github.com/apache/hadoop-common/blob/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn -server-resourcemanager / src / main / java / org / apache / hadoop / yarn / server / resourcemanager / ResourceManager.java
The file can be compiled without errors in its maven project, but its dependencies are not passed to javac in my situation. 可以在其maven项目中编译该文件而不会出错,但是在我的情况下,其依赖项不会传递给javac。 I'm not sure if this is the problem.
我不确定这是否是问题。
The trees.getElement
returns null in the middle part of the code above, while the other parts seems to work well. trees.getElement
在上面代码的中间部分返回null,而其他部分似乎运行良好。
According to this answer , it seems that the Element
s' information is not usable until the compilation is completed. 根据这个答案 ,在编译完成之前,似乎无法使用
Element
的信息。
So calling task.analyze()
solved my problem. 因此,调用
task.analyze()
解决了我的问题。 Although javac is complaining about missing dependencies. 尽管javac抱怨缺少依赖项。
Please correct me if I'm wrong, thanks. 如果我错了,请指正我,谢谢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.