- 追加された行はこの色です。
- 削除された行はこの色です。
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
AbstractTypeDeclaration は型やEnum,Annotationを表現する抽象クラスです。
AbstractTypeDeclaration は型(クラスやインタフェース)やEnum,Annotationを表現する抽象クラスです。
#ref(abstract.png)
List<AbstractTypeDeclaration> CompilationUnit#types();
を呼び出すことでCompilationUnitに記述されている型情報を取得することができます。戻り値がListになっているのは、一つのUnit((=ファイル?))に複数のクラスが書いてある場合があるからですね。ちなみに、[[あるソースコードに書かれているクラス名を全て取得する>Eclipse/プラグイン開発のTIPS集/ソースコードを解析するパーサASTParser/TypeDeclaration#f465918b]] これを使ってもソース内のクラス名などは取得可能です。あちらは
ICompilationUnit =element; <-パッケージエクスプローラなどから取得する
IType[] types = element.getTypes();
といってITypeインタフェースを経由して型情報にアクセスできますね((そもそも、なんで2通りのやり方があるのかはよくわからんです))。。
**Annotationにアクセスしてみる [#s6a7f75d]
対象のCompilationUnitがAnnotationだった場合に、正しくアクセスできるか試してみました。
対象のコードはこんな感じ
-nu.mine.kino.annotations.Service
package nu.mine.kino.annotations;
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Service {
boolean singleton() default false;
}
上のコードを解析するソースはこんな感じです
ASTParser parser = ASTParser.newParser(AST.JLS3);
// parser.setResolveBindings(true);
parser.setSource(unit);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
// parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS);// やったら↓これはNG
CompilationUnit root = (CompilationUnit) parser
.createAST(new NullProgressMonitor());
List<AbstractTypeDeclaration> types = (List<AbstractTypeDeclaration>) root
.types();
for (AbstractTypeDeclaration type : types) {
System.out.println("タイプのクラス名: " + type.getClass().getName());
System.out.println("クラス名: " + type.getName());
// System.out.println("TypeのValue: " + type);
System.out.println("---------");
// そのクラス自体がAnnotationかどうか。
if (type instanceof AnnotationTypeDeclaration) {
System.out.println("Annotationです");
}
}
実行結果です
タイプのクラス名: org.eclipse.jdt.core.dom.AnnotationTypeDeclaration
クラス名: Service
---------
Annotationです
まだAnnotationらしいデータにはアクセスしてないですが、Annotationだってこと自体は確認できました。
次はその型のModifierやAnnotationにアクセスしてみます。Modifierとはいわゆる
public
protected
private
static
abstract
final
native
synchronized
transient
volatile
strictfp
などの修飾子のことですね。AnnotationはまさにAnnotationですね。先の型@Serviceはそれ自体もAnnotationですが、
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Service {
...
などとAnnotationが付与されているため、それらの値も取得できそうです。
実際にModiferやAnnotationにアクセスするメソッドは
List<IExtendedModifier> modifiers = type.modifiers();
です。実際にコードは以下の通りです。
// http://dev.eclipse.org/newslists/news.eclipse.tools.jdt/msg19931.html
List<IExtendedModifier> modifiers = type.modifiers();
// ただし↑は、 @inheritedされて継承されたAnnotationはModifiersとしては返却されないようだ。。
for (IExtendedModifier modifier : modifiers) {
System.out.println("modifier: " + modifier);
if (modifier.isAnnotation()) {
System.out.println("isAnnotation");
Annotation annoModifier = (Annotation) modifier;
if (annoModifier.isSingleMemberAnnotation()) {
System.out.println("isSingleMemberAnnotation");
Expression value = ((SingleMemberAnnotation) annoModifier)
.getValue(); // このクラスにAnnoされている値。
System.out.println(value);
} else if (annoModifier.isMarkerAnnotation()) {
System.out.println("isMarkerAnnotation");
} else if (annoModifier.isNormalAnnotation()) {
System.out.println("isNormalAnnotation");
List<MemberValuePair> list = ((NormalAnnotation) annoModifier)
.values();
for (MemberValuePair pair : list) {
System.out.println("Annotationされている情報: "
+ pair.getName() + "=" + pair.getValue());
}
}
} else {
Modifier normalModifier = (Modifier) modifier;
System.out.println(normalModifier.getKeyword());
}
}
結果は以下の通り
modifier: @Inherited
isAnnotation
isMarkerAnnotation <- マーカー
modifier: @Target(ElementType.TYPE)
isAnnotation
isSingleMemberAnnotation <-SingleMember
ElementType.TYPE <-そのValue
modifier: @Retention(RetentionPolicy.SOURCE)
isAnnotation
isSingleMemberAnnotation <-SingleMember
RetentionPolicy.SOURCE <-そのValue
modifier: public
public
SingleMemberじゃないAnnotationはなかったので表示されませんでしたが、NormalAnnotationの場合は
List<MemberValuePair> list = ((NormalAnnotation) annoModifier).values();
for (MemberValuePair pair : list) {
System.out.println("Annotationされている情報: "
+ pair.getName() + "=" + pair.getValue());
}
などとKey/Value形式でアクセスができそうです。
----
この記事は
#vote(おもしろかった,そうでもない)
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}