モジュール java.compiler

インタフェースProcessor

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


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

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

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

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

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

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

    注釈が存在すると見なされるのは、AnnotatedConstructで指定されている存在の定義を満たしている場合です。 簡潔に言うと、検出の目的で注釈が存在すると見なされるのは、直接存在しているか継承を介して存在している場合です。 注釈がコンテナ注釈よってラップされている場合、存在しているとは見なされません 機能的には、要素に対してElements.getAllAnnotationMirrors(Element)を呼び出した結果に注釈が含まれる場合にかぎり、その注釈はその要素上に存在していることになります。 コンテナ注釈の内側にある注釈は存在していると見なされないため、繰返し可能な注釈型を正しく処理するために、プロセッサはそのサポートしている注釈型のセットに、繰返し可能な注釈型とそれを含有する注釈型の両方を含めるようにしてください。

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

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

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

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

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

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

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

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

      • getSupportedOptions

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

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

        SupportedOptionString:
        Identifiers
        Identifiers:
        Identifier
        Identifier . Identifiers
        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:
        . *
        ここで、TypeNameModuleName「Java™言語仕様」で定義されているとおりです。
        APIの注:
        モジュールをサポートする環境で実行する場合、プロセッサは、サポートされている注釈のタイプを記述する際に、モジュール・プレフィクスを含めることが推奨されます。 メソッドAbstractProcessor.getSupportedAnnotationTypesは、モジュールのない環境で実行しているときにモジュール・プレフィクスを取り除くためのサポートを提供します。
        戻り値:
        このプロセッサがサポートする注釈型の名前
        関連項目:
        SupportedAnnotationTypes
        Java™言語仕様:
        3.8 識別子、6.5名前の意味の決定
      • 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 Arrays.asList(of("3"),
                              of("7"),
                              of("31"),
                              of("127"),
                              of("8191"),
                              of("131071"),
                              of("524287"),
                              of("2147483647"));
         
        コンプリートのセットに次のように素数の値が含まれていれば、より有益になります。
         return Arrays.asList(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 - コンプリートの対象となるソース・コード・テキスト
        戻り値:
        注釈に対する推奨のコンプリート