Java Compiler API を使用して .java ファイルを分析しようとしています。私の現在の問題は、特定の変数、メソッド、またはクラスがプログラム内の特定のスコープで認識されているかどうかを調べることです (スコープとは、Java コンパイラ API 自体で定義されているスコープを意味します。こちらを参照してください: http:// docs.oracle.com/javase/6/docs/jdk/api/javac/tree/com/sun/source/tree/Scope.html )。
Java コンパイラ API の Trees クラス ( http://docs.oracle.com/javase/6/docs/jdk/api/javac/tree/com/sun/source/util/Trees.html ) には、次のユーティリティ メソッドがあります。それをしてください:isAccessible。このメソッドは、Scope とターゲット ノード、およびその宣言された型を取得し、指定されたスコープでターゲット ノードが既知の場合は true を返します。
残念ながら、この DeclaredType オブジェクトを作成する方法はわかりません (スタックオーバーフローのスパム防止のため、今後はクラス名のみを記述し、ハイパーリンクを投稿することはできません: javax.lang.model.type.DeclaredType)。ターゲット Node にそのタイプ (javax.lang.model.element.Element [asType() メソッド]) を問い合わせることができますが、それは DeclaredType ではなく TypeMirror インスタンスを返します。
現在、次の 2 行のコードを使用しています。
final DeclaredType nodeType = (DeclaredType) nodeTypeMirror;
isAccessible = referenceCompTree.isAccessible(referenceScope, nodeElement, nodeType);
ここで、「referenceCompTree」は現在のプログラムのツリー インスタンス、referenceScope は問題のスコープ、nodeElement は問題のノード、nodeType は問題のノードの DeclaredType である必要があります。
この直接型キャスト アプローチは、クラスのノードである 1 つのケースでうまく機能します (ノードが独自の型を宣言し、その typeMirror が独自の型と同等であるため、これが機能すると思います)。しかし、(ヘッダーに記載されているように) プリミティブ型の変数に対しては確実に機能しません。変数に対して機能するかどうかはわかりません。
誰か知っていますか
- プリミティブ型に Trees の isAccessible-method を使用する方法、またはより具体的には、TypeMirror インスタンスを DeclaredType インスタンスに一般的に変換する方法は? また
- isAccessibleを使用せずに必要な情報を取得する方法(変数、クラス、またはメソッドが特定のスコープで既知の場合)?
付録:
両方の質問についてさらに調査を行ったので、わかったことのいくつかを紹介したいと思います。
- タイプ (javax.lang.model.util.Types) と呼ばれるユーティリティ クラスがあります。型のインスタンスは、標準の Java コンパイラ API クラス (この場合は com.sun.source.util.JavaTask) を使用して取得できます。このオブジェクトには、指定された TypeElement といくつかの TypeMirror の DeclaredType インスタンスを返すメソッド (getDeclaredType) があります。しかし、この方法は、入力引数が少なかったことを示すエラーがスローされるため、私には機能しません。このメソッドには、指定された生のクラスといくつかの型パラメーターの DeclaredType インスタンスを返すという唯一の目的があると思います (たとえば、HashMap の DeclaredType インスタンスを作成するには、このメソッドを HashMap の typeElement と String の 2 つの typeMirrors と共に使用します)。明らかに、これは私が意図していることではありません。
- それぞれの修飾子を検索し、スコープ ツリーを検索して、変数、クラス、またはメソッドが特定のスコープで既知であるかどうかを手動で判断することで、回避策をプログラムしようとしましたが、主な理由が 2 つあります。検索アルゴリズムでJavaスコープ構築のすべての特殊なケースを正しく取得したかどうかはわかりません.2番目に、(一見)既に存在し、Javaコンパイラが常に行うものを再実装しようとするため、これは非常に不必要に思えます。地獄、私の NetBeans でさえ、特定の変数、メソッド、またはクラスが現在のスコープで既知であるかどうかを常に教えてくれます。ですから、何らかの方法があるはずです。