モジュール java.compiler

インタフェースProcessor

既知のすべての実装クラス:
AbstractProcessor

public interface Processor
注釈プロセッサのインタフェース。

注釈処理は、一連のラウンド内で実行されます。 各ラウンドでは、前回のラウンドで生成されたソース・ファイルとクラス・ファイルで見つかった注釈のサブセットの処理を、あるプロセッサが依頼される可能性があります。 1回目の処理ラウンドへの入力はツールの実行への初期入力になりますが、これらの初期入力は、仮想的な0回目の処理ラウンドの出力とみなすことができます。 あるプロセッサが特定のラウンドで処理を依頼された場合、たとえそのプロセッサの処理対象となる注釈が存在しない場合でも、そのプロセッサは最終ラウンドを含む後続のラウンドでも処理を依頼されます。 また、ツール・インフラストラクチャは、そのツールの操作によって暗黙的に生成されたファイルの処理を、プロセッサに依頼することもあります。

Processorの各実装では、ツールがプロセッサをインスタンス化するために使用するpublic引数なしコンストラクタを提供する必要があります。 ツール・インフラストラクチャとこのインタフェースを実装したクラスとの相互作用は、次のようになります。

  1. 既存のProcessorオブジェクトが使用されない場合、ツールは、あるプロセッサのインスタンスを作成するために、そのプロセッサのクラスの引数なしコンストラクタを呼び出す。
  2. 次に、ツールによって、適切なProcessingEnvironmentinitメソッドがコールされます。
  3. その後、ツールは、getSupportedAnnotationTypesgetSupportedOptions、およびgetSupportedSourceVersionを呼び出す。 これらのメソッドが呼び出されるのは、実行ごとに1回だけである。ラウンドごとに1回ではない。
  4. ツールは必要に応じて、Processorオブジェクトのprocessメソッドを呼び出す。ラウンドごとに新しいProcessorオブジェクトが作成されるわけではない
上記のプロトコルに従わずにプロセッサ・オブジェクトが作成および使用された場合、そのプロセッサの動作はこのインタフェース仕様では定義されません。

ツールは、検出処理を使って注釈プロセッサを見つけ出し、それらを実行すべきかどうかを決定します。 ツールを構成することで、可能性のあるプロセッサのセットを制御できます。 たとえば、JavaCompilerの場合、実行候補プロセッサのリストは、直接設定することも、サービススタイルの検索で使用される検索パスを使って制御することもできます。 ほかのツール実装は、コマンド行オプションなど、別の構成メカニズムを備えている可能性もありますが、その詳細については、特定のツールのドキュメントを参照してください。 ツールがrunに要求するプロセッサは、「ルート要素」上の注釈presentのインタフェースの機能、「プロセッサがサポートする注釈インタフェース」およびプロセッサ「処理する注釈インタフェースを要求」かどうかです。 プロセッサは、サポートする注釈インタフェースのサブセット(空のセットの場合もある)を処理するよう求められます。 ツールは、指定されたラウンドについて、ルート要素内に囲まれた要素に存在する注釈インタフェースのセットを計算します。 少なくとも1つの注釈インタフェースが存在する場合、プロセッサが注釈インタフェースを要求すると、それらは一致しない注釈インタフェースのセットから削除されます。 このセットが空になるか、使用可能なプロセッサがなくなると、そのラウンドは終了します。 注釈インタフェースが存在しない場合でも、注釈処理は行われますが、(empty)の注釈インタフェースのセットを要求できるのは、すべての注釈インタフェースの処理をサポートする「汎用プロセッサ」"*"のみです。

ラウンドのルート要素内に囲まれた要素に、そのインタフェースの注釈が少なくとも1つ存在する場合、注釈インタフェースは存在すると見なされます。 この目的のために、型パラメータはそのジェネリック要素で囲まれていると見なされます。 このため、パッケージ要素は、そのパッケージ内のトップレベルのクラスおよびインタフェースを囲むものとはみなされません。 (パッケージを表すルート要素は、package-infoファイルが処理されるときに作成されます。) 同様に、この目的のために、モジュール要素は、そのモジュール内にパッケージを囲むとはみなされません。 (module-infoファイルが処理されると、モジュールを表すルート要素が作成されます。) 「型の使用」の注釈は、要素の注釈とは対照的に、注釈インタフェースが存在するかどうかを計算するときに無視されます。

注釈は、AnnotatedConstructで特定される定義を満たす場合、presentです。 簡潔に言うと、検出の目的で注釈が存在すると見なされるのは、直接存在しているか継承を介して存在している場合です。 注釈がコンテナ注釈よってラップされている場合、存在しているとは見なされません 機能的には、要素に対してElements.getAllAnnotationMirrors(Element)を呼び出した結果に注釈が含まれる場合にかぎり、その注釈はその要素上に存在していることになります。 コンテナ注釈内の注釈は存在しないとみなされるため、「繰返し可能な注釈インタフェース」を適切に処理するには、プロセッサの「サポートされている注釈インタフェース」セットに繰返し可能な注釈インタフェースとそれを含む注釈インタフェースの両方を含めることをお薦めします。

"*"をサポートするプロセッサが trueを返すと、すべての注釈が要求されます。 したがって、たとえば、追加の妥当性チェックの実装に使用される汎用プロセッサは、falseを返すべきです。そうすれば、ほかのそのようなチェッカの実行を妨げずにすみます。

あるプロセッサがキャッチされない例外をスローすると、ツールは、ほかのアクティブな注釈プロセッサを中止する可能性があります。 あるプロセッサがエラーを発行すると、現在のラウンドは終了し、後続のラウンドが、エラーが発行されたことを通知します。 注釈プロセッサは協調的な環境内で実行されるため、キャッチされない例外をプロセッサからスローするのは、エラーの復旧や報告が実行不可能な場合に限るべきです。

ツール環境は、ラウンドごとに、あるいはラウンドをまたがって、マルチ・スレッド方式で環境リソースにアクセスする注釈プロセッサをサポートする必要はありません。

注釈プロセッサに関する構成情報を返すメソッドがnullを返したか、その他の無効な入力を返したか、あるいは例外をスローした場合、ツール・インフラストラクチャはそれをエラー状態とみなします。

ある注釈プロセッサをさまざまなツール実装内で実行させる場合、その動作を安定させるには、そのプロセッサは次の特性を備えているべきです。

  1. ある入力の処理結果がほかの入力の存在有無に依存しない(直交性)。
  2. 同じ入力を処理した場合には同じ出力が得られる(一貫性)。
  3. 入力Aを処理したあとに入力Bを処理することと、BのあとにAを処理することが、等価である(交換性)。
  4. ある入力の処理が、ほかの注釈プロセッサからの出力の存在に依存しない(独立性)。

Filerインタフェースでは、プロセッサがどのようにファイルを操作できるかに関する制限について説明しています。

APIのノート:
このインタフェースの実装者は、このインタフェースを直接実装するのではなく、AbstractProcessorを拡張するほうが便利かもしれません。
導入されたバージョン:
1.6
  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    Iterable<? extends Completion>
    getCompletions​(Element element, AnnotationMirror annotation, ExecutableElement member, String userText)
    ある注釈に対する推奨のコンプリートから成る反復可能オブジェクトを、ツール・インフラストラクチャに返します。
    このプロセッサがサポートする注釈インタフェースの名前を返します。
    このプロセッサが認識するオプションを返します。
    この注釈プロセッサがサポートする最新ソース・バージョンを返します。
    void
    init​(ProcessingEnvironment processingEnv)
    指定された処理環境を使用してプロセッサを初期化します。
    boolean
    process​(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
    前のラウンドから発生した型要素の注釈インタフェースのセットを処理し、これらの注釈インタフェースがこのプロセッサによって要求されているかどうかを返します。
  • メソッドの詳細

    • getSupportedOptions

      Set<String> getSupportedOptions()
      このプロセッサが認識するオプションを返します。 処理ツールの実装は、ツール自体に渡すオプションとは別に、プロセッサ固有のオプションを渡す方法を提供しなければいけません。getOptionsを参照してください。

      セット内に返される各文字列は、次のような、ピリオドで区切られた一連の識別子になります。

      SupportedOptionString:
      識別子
      識別子:
      Identifier
      Identifier 識別子
      Identifier:
      キーワードやリテラルといった、構文上の識別子

      ツールは、この情報を使って、ユーザーが指定したオプションをプロセッサが認識するかどうかを判定します。認識しない場合、ツールは警告を報告します。

      戻り値:
      このプロセッサが認識するオプション。存在しない場合は空のセット
      関連項目:
      SupportedOptions
    • getSupportedAnnotationTypes

      Set<String> getSupportedAnnotationTypes()
      このプロセッサがサポートする注釈インタフェースの名前を返します。 結果の要素は、サポートされている注釈インタフェースの正規の(完全修飾)名である場合があります。 または、"name."で始まる正規名を持つすべての注釈インタフェースのセットを表す"name.*"の形式にすることもできます。 いずれの場合も、オプションで、注釈インタフェースの名前の前にモジュール名と "/"文字を付けることができます。 たとえば、プロセッサが "a.B"をサポートしている場合、これには、異なるモジュールに存在する a.Bという名前の複数の注釈インタフェースを含めることができます。 fooモジュールで a.Bのみをサポートするには、かわりに"foo/a.B"を使用してください。 モジュール名が含まれている場合、そのモジュール内の注釈のみが一致します。 特に、モジュールがサポートされていない環境(モジュールのない「ソース・バージョン」用に構成された注釈処理環境など)でモジュール名が指定された場合、モジュール名を持つ注釈インタフェースは一致しません。 最後に、"*"自体が、空のセットを含むすべての注釈インタフェースのセットを表します。 プロセッサは、実際にすべてのファイルを処理するのでないかぎり、"*"を要求すべきではありません。不要な注釈を要求した場合、環境によってはパフォーマンスが低下する可能性があります。

      セット内に返される各文字列は、次の文法に受け入れられるものでなければいけません。

      SupportedAnnotationTypeString:
      ModulePrefix opt TypeName DotStar opt
      *
      ModulePrefix:
      ModuleName /
      DotStar:
      . *
      ここで、TypeNameおよびModuleNameは、「Java言語仕様」 (「6.5 名前の意味の決定」)で定義されているとおりです。

      APIのノート:
      モジュールをサポートする環境で実行する場合、プロセッサは、サポートされている注釈インタフェースを記述するときにモジュール・プレフィクスを含めることをお薦めします。 メソッドAbstractProcessor.getSupportedAnnotationTypesは、モジュールのない環境で実行しているときにモジュール・プレフィクスを取り除くためのサポートを提供します。
      戻り値:
      このプロセッサがサポートする注釈インタフェースの名前。存在しない場合は空のセット
      Java言語仕様を参照してください:
      3.8 識別子
      関連項目:
      SupportedAnnotationTypes
    • getSupportedSourceVersion

      SourceVersion getSupportedSourceVersion()
      この注釈プロセッサがサポートする最新ソース・バージョンを返します。
      戻り値:
      この注釈プロセッサがサポートする最新ソース・バージョン
      関連項目:
      SupportedSourceVersion, ProcessingEnvironment.getSourceVersion()
    • init

      void init(ProcessingEnvironment processingEnv)
      指定された処理環境を使用してプロセッサを初期化します。
      パラメータ:
      processingEnv - ツール・フレームワークがプロセッサに対して提供する機能に対する環境
    • process

      boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
      前のラウンドから発生した型要素の注釈インタフェースのセットを処理し、これらの注釈インタフェースがこのプロセッサによって要求されているかどうかを返します。 trueが返された場合、注釈インタフェースは要求され、後続のプロセッサはそれらを処理するように要求されません。falseが返された場合、注釈インタフェースは要求されず、後続のプロセッサはそれらを処理するように要求されることがあります。 プロセッサは、常に同じブール値を返すか、またはそれ自身の選択した基準に基づいて結果を変えることができます。

      プロセッサが "*"をサポートしていてルート要素が注釈を1つも持たない場合、入力のセットは空になります。 Processorは空の注釈セットを適切に処理しなければいけません。

      パラメータ:
      annotations - 処理をリクエストされた注釈インタフェース
      roundEnv - 現在および前回のラウンドについての情報に対する環境
      戻り値:
      注釈インタフェースのセットがこのプロセッサによって要求されているかどうか
    • getCompletions

      Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText)
      ある注釈に対する推奨のコンプリートから成る反復可能オブジェクトを、ツール・インフラストラクチャに返します。 コンプリートが要求されているため、ソース・コード・フラグメントの場合のように、注釈について提供される情報が不完全である可能性があります。 プロセッサは、空の反復可能オブジェクトを返すことができます。 注釈プロセッサは、値が1から10の範囲に収まるべきintメンバーや、正規表現やURLのような、ある既知の文法によって認識されるべき文字列メンバーなど、プロセッサに既知の追加妥当性制約を持つ注釈メンバーに対するコンプリートを提供することに、努力を集中させるべきです。

      不完全なプログラムのモデル化が行われているため、いくつかのパラメータは、部分的な情報しか持たなかったり、 nullであったりする可能性があります。 1個以上のelementおよびuserTextnull以外の値である必要があります。 elementが非nullである場合、annotationおよびmember nullであり得る。 プロセッサは、一部のパラメータがnullでもNullPointerExceptionをスローできません。指定された情報に基づいて提供すべきコンプリートをプロセッサが1つも持たない場合、空の反復可能オブジェクトを返すことができます。 また、プロセッサは、空の値文字列と、コンプリートが存在しない理由を説明したメッセージとを含む単一のコンプリートを返すこともできます。

      コンプリートは有益な情報であり、注釈プロセッサによって実行される追加妥当性チェックを反映する場合があります。 たとえば、次のような単純な注釈があるとします。

       @MersennePrime {
          int value();
       }
       
      メルセンヌ素数とは、2n - 1の形式の素数のことを指します。 この注釈インタフェースのAnnotationMirrorを指定すると、getCompletionsへのほかの引数を検査せずに、int範囲内のそのようなすべての素数のリストを返すことができます:
       import static javax.annotation.processing.Completions.*;
       ...
       return List.of(of("3"),
                      of("7"),
                      of("31"),
                      of("127"),
                      of("8191"),
                      of("131071"),
                      of("524287"),
                      of("2147483647"));
       
      コンプリートのセットに次のように素数の値が含まれていれば、より有益になります。
       return List.of(of("3",          "M2"),
                      of("7",          "M3"),
                      of("31",         "M5"),
                      of("127",        "M7"),
                      of("8191",       "M13"),
                      of("131071",     "M17"),
                      of("524287",     "M19"),
                      of("2147483647", "M31"));
       
      ただし、userTextが使用可能である場合には、その値をチェックすることで、メルセンヌ素数のサブセットのみが有効かどうかを判断できます。 たとえば、ユーザーが次のように入力したとします。
      @MersennePrime(1
      userTextの値は"1"になります。したがって、可能なコンプリートは次の2つの素数だけになります。
       return Arrays.asList(of("127",        "M7"),
                            of("131071",     "M17"));
       
      有効なコンプリートが存在しない場合もあります。 たとえば、9で始まるメルセンヌ素数は、範囲内では存在しません。
      @MersennePrime(9
      この場合の適切な応答としては、次のように空のコンプリート・リストを返すか、
       return Collections.emptyList();
       
      あるいは、次のように、有用なメッセージを含む単一の空コンプリートを返します。
       return Arrays.asList(of("", "No in-range Mersenne primes start with 9"));
       

      パラメータ:
      element - 注釈が付けられる要素
      annotation - 要素に適用される(おそらく部分的な)注釈
      member - 可能なコンプリートを返す対象となる注釈メンバー
      userText - コンプリートの対象となるソース・コード・テキスト
      戻り値:
      注釈に対する推奨のコンプリート