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形式でアクセスができそうです。 この記事は 現在のアクセス:9515 |