#author("2021-12-14T02:32:37+00:00","","") // 下階層用テンプレート #topicpath ---- //ここにコンテンツを記述します。 #contents 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(おもしろかった[1],そうでもない[0]) #vote(おもしろかった[2],そうでもない[0]) #comment #topicpath SIZE(10){現在のアクセス:&counter;}