5

javac の Compiler Tree API を使用してソース コード分析を行う JSR 269 形式の注釈プロセッサを作成しようとしています。メソッド呼び出しなどのメンバー選択式に興味があります。

選択されているメソッド (またはフィールドなど) の名前を簡単に取得できます。しかし、メンバーがどのタイプから選択されているかを知りたいのですが、これを行う簡単な方法を見つけることができないようです. Trees.getTypeMirror私がそれを呼び出しようとしたすべてに対して返さnullれます(そしてJavadocはヒントを与えません)。

メンバー select の左側にあるあらゆる種類の式を徹底的に分析し、再帰的分析によって式の静的な型を決定できると思います: NewClassTreeTypeCastTreeMethodInvocationTreeArrayAccessTree、およびその他多数。しかし、これは多くのエラーが発生しやすい作業のように見えます。明らかに javac は、多くの目的でこの情報を必要とするため、式の静的型をすでに認識しています。しかし、この型情報にアクセスするにはどうすればよいでしょうか?

私がこれまでに持っているもの:

import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreePathScanner;
import com.sun.source.util.Trees;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class PublicProcessor extends AbstractProcessor {
    public @Override boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getRootElements()) {
            final Trees trees = Trees.instance(processingEnv);
            final TreePath root = trees.getPath(e);
            new TreePathScanner<Void,Void>() {
                public @Override Void visitMethodInvocation(MethodInvocationTree node, Void p) {
                    System.err.println("visiting method invocation: " + node + " of kind: " + node.getMethodSelect().getKind());
                    TreePath expr = TreePath.getPath(root, node);
                    System.err.println("  of type: " + trees.getTypeMirror(expr));
                    return super.visitMethodInvocation(node, p);
                }
                public @Override Void visitMemberSelect(MemberSelectTree node, Void p) {
                    System.err.println("accessing member: " + node.getIdentifier());
                    System.err.println("  from: " + getCurrentPath().getCompilationUnit().getSourceFile().toUri());
                    TreePath expr = TreePath.getPath(root, node.getExpression());
                    System.err.println("  in expr: " + expr.getLeaf());
                    System.err.println("  of type: " + trees.getTypeMirror(expr));
                    return super.visitMemberSelect(node, p);
                }
            }.scan(root, null);
        }
        return true;
    }
}

そして、メソッド呼び出しを行ういくつかの単純なコードで実行したときに出力されるもの:

visiting method invocation: new Class().method() of kind: MEMBER_SELECT
  of type: null
accessing member: method
  from: .../Whatever.java
  in expr: new Class()
  of type: null
4

1 に答える 1

1

Annotation Processor for Java でメソッド呼び出しのクラスを発見する

非常によく似た質問に対処しているように見えるので、そこで与えられたアドバイスを使用しようとします。残念ながら、それは単純に見えず、com.sun.tools.javacパッケージの使用が必要なようです。

于 2010-01-23T19:00:03.447 に答える