简体   繁体   English

学习Java编译器API,为什么trees.getElement(treepath)返回null?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM