|
AbstractTypeDeclaration? は型(クラスやインタフェース)やEnum,Annotationを表現する抽象クラスです。 List<AbstractTypeDeclaration> CompilationUnit#types(); を呼び出すことでCompilationUnit?に記述されている型情報を取得することができます。戻り値がListになっているのは、一つのUnit*1に複数のクラスが書いてある場合があるからですね。ちなみに、あるソースコードに書かれているクラス名を全て取得する これを使ってもソース内のクラス名などは取得可能です。あちらは ICompilationUnit =element; <-パッケージエクスプローラなどから取得する IType[] types = element.getTypes(); といってITypeインタフェースを経由して型情報にアクセスできますね*2。。 Annotationにアクセスしてみる †対象のCompilationUnit?がAnnotationだった場合に、正しくアクセスできるか試してみました。 対象のコードはこんな感じ
上のコードを解析するソースはこんな感じです 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形式でアクセスができそうです。 この記事は 現在のアクセス:9747 |