ここにはいくつかの問題があります。メソッド呼び出しレシーバーの Java タイプを知りたい場合もあれば、呼び出されるメソッドのクラスを知りたい場合もあります。Java 情報は、ジェネリック型も提供するため、より有益です。たとえばList<String>
、要素はクラスのみを提供しますが、List<E>
.
要素を取得する
メソッドが呼び出されるクラスの Element を取得するには、次のようにします。
MethodInvocationTree node = ...;
Element method =
TreeInfo.symbol((JCTree)node.getMethodSelect());
TypeElement invokedClass = (TypeElement)method.getEnclosingElement();
コーナーケース:
1. invokedClass はレシーバー型のスーパークラスである場合があります。したがって、 equals() はnotで実装されているため、スニペットを実行するとではなくnew ArrayList<String>.equals(null)
が返さ
れます。AbstractList
ArrayList
AbstractList
ArrayList
2. 配列の呼び出しを処理する場合、たとえばのクラスnew int[].clone()
を取得します。TypeElement
Array
実際の型を取得する
型を取得するために、受信者の型が何であるかを直接判断する方法はありません。レシーバーが明示的に指定されていない内部クラス内でのメソッド呼び出しの処理には、多少の複雑さがあります (たとえば、 とは異なりOuterClass.this.toString()
ます)。実装例を次に示します。
MethodInvocationTree node = ...;
TypeMirror receiver;
if (methodSel.getKind() == Tree.Kind.MEMBER_SELECT) {
ExpressionTree receiver = ((MemberSelectTree)methodSel).getExpression();
receiverType = ((JCTree)receiver).type;
} else if (methodSel.getKind() == Tree.Kind.IDENTIFIER) {
// need to resolve implicit this, which is described in
// JLS3 15.12.1 and 15.9.2
// A bit too much work that I don't want to work on now
// Look at source code of
// Attr.visitApply(JCMethodInvocation)
// resolveImplicitThis(DiagnosticPosition, Env, Type)
} else
throw new AssertionError("Unexpected type: " + methodSel.getKind());
ノート:
残念ながら、receiver
タイプはそうである必要はありTypeMirror
ません。DeclaredType
を呼び出すとnew int[5].clone()
、以前のメソッドよりも有益なofにreceiver
なります。ArrayType
int[]
実行する
前の方法はどちらも、クラスの型情報を解決するためにコンパイラを必要とします。通常、コンパイラはメソッド宣言の型のみを解決し、本体は解決しません。したがって、前述のメソッドがnull
代わりに返されます。
コンパイラに型情報を解決させるには、次のいずれかの方法を実行できます。
1. JDK 7 のコンパイラ リポジトリに追加されたばかりのクラスを使用します。JSR 308とそのコンパイラAbstractTypeProcessor
に関する作業を確認してください。作業は主に注釈付きの型に関するものですが、役に立つかもしれません。コンパイラを使用すると、提供されたクラスを Java 5 と下位互換性のある方法で使用できます。
このアプローチにより、現在のプロセッサと同じように呼び出されるプロセッサを作成できます。
2.JavacTask
代わりに を使用して呼び出しますJavacTask.analyze()
。この javac テストのメイン メソッドを見て、クラスでビジターを呼び出す方法を確認してください。
このアプローチにより、通常のプロセスではなく直接呼び出す必要があるため、プロセッサはコンパイラへのプラグインではなく分析ツールのように見えます。