M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

ProGuardマニュアル(15) クラス指定

原文は、ProGuard Manual”(Eric Lafortune)です(2011年3月29日取得)。

イントロダクションと索引はこちら

******************************

クラス指定

クラス指定は、クラスとクラス・メンバー(フィールドとメソッド)のテンプレートです。種々の-keepオプションと-assumenosideeffectsオプションで使用されます。クラス指定をともなうこれらのオプションは、このテンプレートにマッチするものにのみ有効となります。

このテンプレートは、ワイルドカードによるいくつかの拡張をともなう非常にJava的な記述形式をとるよう設計されています。その構文の実感を得てもらうためには、たぶんExamplesの節を見てみるべきでしょう。ここではテンプレートの形式定義の完全なかたちを示します:

[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
   [extends|implements [@annotationtype] classname]
[{
   [@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
                                                                     (fieldtype fieldname);
   [@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
                                                                                          <init>(argumenttype,...) |
                                                                                          classname(argumenttype,...) |
                                                                                          (returntype methodname(argumenttype,...));
   [@annotationtype] [[!]public|private|protected|static ... ] *;
   ...
}]

矩形括弧“[ ]”は、それが囲んでいる要素がオプションであることを示しています。|(ヴァーティカルバー)は2つの候補を区切るものです。

太字でない括弧“( )”は、グループを成す要素をまとめるものです。インデントは、コードの意味するところを明白にする目的で使用されています。ホワイトスペースは、コンフィギュレーションファイル内では無視されます。

  • classキーワードは、任意のインターフェースもしくはクラスに対応します。interfaceキーワードは、厳密にインターフェースにのみマッチします。enumキーワードは厳密に列挙型にマッチします。!(否定素子)が先頭につけられたinterfaceもしくはenumキーワードは、それぞれ、インターフェースでないクラスもしくは列挙型でないクラスにマッチします。(訳者: 「インターフェースでないクラス」には列挙型が含まれますし、「列挙型でなくクラス」にはインターフェースが含まれることに注意してください。)
  • クラス名は例えばjava.lang.Stringのように、すべて完全名でなくてはなりません。クラス名は、次に示すワイルドカードを含んだ正規表現でも指定できます。
? クラス名の中の任意の1文字にマッチします。パッケージ区切り文字は含まれません。例えば、“”という正規表現は、“mypackage.Test1”と“mypackage.Test2”にマッチします。しかし“mypackage.Test12”にはマッチしません。
* クラス名の中の任意の部分にマッチしますが、パッケージ区切り文字は含みません。例えば“mypackage.*Test*”という正規表現は、“mypackage.Test”と“mypackage.YourTestApplication”にマッチしますが、“mypackage.mysubpackage.MyTest”にはマッチしません。あるいは、より一般的に“mypackage.*”という正規表現は、mypackageパッケージ内のすべてのクラスにマッチしますが、mypackageパッケージのサブパッケージ内のそれにはマッチしません。
** クラス名の中の、パッケージ区切り文字を含む任意の部分にマッチします。例えば、“**.Test”というせいきひょうは、rootパッケージを除くすべてのパッケージのすべてのTestクラスにマッチします。あるいはまた“mypackage.**”という正規表現は、mypackageパッケージとそのサブパッケージ内のすべてのクラスにマッチします。
  • さらなる柔軟性のために、クラス名記述には、ファイル・フィルター同様、否定素子!を含むカンマ区切りのクラス名をリストすることができます。この記述形式はまったくJava的ではありませんから、適度な使用にとどめておきましょう。
  • 利便性と後方互換性のために、クラス名記述を単に“*”とした場合、パッケージにかかわらずすべてのクラスが参照されます。
  • extendsおよびimplements指定は、しばしばワイルドカードをともなうクラス指定をより厳密なものにするために使用されます。2つの指定は、現状では、指定したクラスを拡張もしく実装しているクラスのみを指定するのと同じです。これらの指定により処理対象となる(あるいは対象外となる)クラスの一覧に、extendsもしくはimplementsキーワードの後続のクラス自身は含まれないことに注意してください。それらを含めなくてはならない場合は、別途指定してください。
  • @指定は、指定したアノテーション型に関連付けられたクラスおよびクラス・メンバーを特定するものです。アノテーション型の指定は、クラス名のそれと同様です。
  • フィールドとメソッドの指定は、メソッドの引数リストが(JavadocやJavapといった他のツールのように)仮引数名を含まない点を除けば、Javaソースコードと同様です。メンバー指定には、次に示す包括的ワイルドカード表記を含めることができます:
任意のコンストラクタにマッチします。
任意のフィールドにマッチします。
任意のメソッドにマッチします。
* 任意のフィールドもしくはメソッドにマッチします。
? メソッド名内の任意の1文字にマッチします。
* メソッド名内の任意の部分にマッチします。
% 任意の基本型(boolean、int、エトセトラ。しかしvoidは含まれない)にマッチします。
? クラス名内の任意の1文字にマッチします。
* クラス名内の、パッケージ区切り文字を含まない任意の部分にマッチします。
** クラス名内の、パッケージ区切り文字を含む、任意の部分にマッチします。
*** いかなる型にもマッチします(基本型であるかどうか、配列であるかどうかにかかわらず)。
... いかなる型の、またいかなる数の引数にもマッチします。
  • ?*、そして**ワイルドカードは、決して基本型にはマッチしない点に注意してください。また、***ワイルドカードのみが、任意の次元数の配列型にマッチします。例えば、“** get*()”という記述は、“java.lang.Object getObject()”にはマッチしますが、“float getFloat()”や“java.lang.Object[] getObjects()”にはマッチしません。
  • コンストラクタは、短いクラス名(パッケージ名をともなわない)でも完全クラス名でも指定することができます。Javaソースコードと同様、コンストラクタ指定は引数リストは持ちますが、返値型は持ちません。
  • クラス・アクセス修飾子と、クラス・メンバー・アクセス修飾子は、一般に、ワイルドカードを使用して記述されたクラスもしくはクラス・メンバーをより厳密に特定するために使用されます。これにより、当該アクセス修飾子が設定されているメンバーのみがマッチするようになります。!(否定素子)が先頭についていた場合、当該アクセス修飾子が指定されていないメンバーのみがマッチするようになります。
  • 複数の修飾子を組み合わせることが可能です(例えば、“public static”というように)。複数の修飾子が指定された場合、それらの修飾子がともに設定されていること(例えば、publicかつstatic)がマッチの条件になります。ただし、互いに矛盾するアクセス修飾子が指定されている場合は、それらのうち少なくとも1つが設定されていること(例えば、少なくともpublicもしくはprotected)がマッチの条件になります。
  • さらにProGuardは、syntheticbridge、そしてvarargsというコンパイラにより設定される修飾子をサポートしています。

Copyright 〓 2002-2011 Eric Lafortune.

******************************

以上、ProGuardマニュアルのうち、Usage節までを抜き出して掲載してきました。