簡體   English   中英

學習Java編譯器API,為什么trees.getElement(treepath)返回null?

[英]Learning Java Compiler APIs,why does trees.getElement(treepath) return null?

我正在嘗試使用Java編譯器API解析Java文件。

文件很差。 經過數小時的挖掘,我仍然無法為我使用Trees#getElement 這是我的代碼:

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);
        }
    }
}

添加了有關params-sourcepath的行,因為我認為編譯器試圖在錯誤的位置找到源文件。 他們沒有工作。

我仍在嘗試了解Trees ,javac和相關的JSR如何一起工作,是否有針對初學者的推薦文檔? 謝謝你的幫助。

編輯:我想分析的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

可以在其maven項目中編譯該文件而不會出錯,但是在我的情況下,其依賴項不會傳遞給javac。 我不確定這是否是問題。

trees.getElement在上面代碼的中間部分返回null,而其他部分似乎運行良好。

根據這個答案 ,在編譯完成之前,似乎無法使用Element的信息。

因此,調用task.analyze()解決了我的問題。 盡管javac抱怨缺少依賴項。

如果我錯了,請指正我,謝謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM