VisitorのうちTypeDeclaration? を引数に取る

public boolean visit(TypeDeclaration node);

はクラスのいろいろな情報がとれそうです。

TypeDeclaration? はあるソースコード内の一つのクラスに対応しています。TypeDeclaration? からそのクラスのクラス名は?とか親インタフェースは?とか、いろいろ取得できるわけですね。

対象のクラス

  • nu.mine.kino.IBL インタフェース
    package nu.mine.kino;
    
    public interface IBL {
      void exe();
      String exe(String hoge);
    }
  • nu.mine.kino.BL クラス
    package nu.mine.kino;
    
    import java.io.Serializable;
    
    public class BL implements IBL, Serializable {
      private final String field;
    
      public BL() {
        System.out.println("Constructor");
        field = "";
      }
    
      public BL(String field) {
        System.out.println("Constructor");
        this.field = field;
      }
    
      public void exe() {
        System.out.println("hoge");
    
      }
    
      public String exe(String hoge) {
        System.out.println(hoge);
        return hoge;
      }
    }

いろいろ試してみる

実装しているインタフェースを取得する

上のBLに対して

List interfaces = node.superInterfaceTypes();

を実行するとorg.eclipse.jdt.core.dom.SimpleType?のListが取得できます。このSimpleType?に対して、

SimpleType#getName();

とすることで実装しているインタフェース名が取得できます。

ソースコード内に登場するクラスのパッケージ名を取得する

苦労しました。以下のような感じ??elementは ICompilationUnit? です。

List superInterfaceTypes = node.superInterfaceTypes();
logger.debug("SuperInterfaceTypes: " + superInterfaceTypes);
try {
  // ソースコードの文字列を取得
  String source = element.getSource();
  // 取得したインタフェース名でループ
  for (Object interfaze : superInterfaceTypes) {
    Type typee = (Type) interfaze;
    // System.out.println(typee.toString());
    int start = source.indexOf(typee.toString());
    int length = typee.toString().length();

    // 上のstart,lengthで挟まれる部分から、IJavaElementを生成
    IJavaElement[] elements = element.codeSelect(start, length);
    for (IJavaElement element : elements) {
      logger.debug("Path: " + element.getPath().toOSString());
      logger.debug("Element Name: "
          + element.getElementName());
      // elementがITypeだったら、
      if (element.getElementType() == IJavaElement.TYPE) {
        logger.debug(element.getElementName() + "はITYPEです");
        IType type = (IType) element;
        logger.debug("パッケージ名: "
            + type.getPackageFragment()
                .getElementName());
      }

    }
  }

} catch (JavaModelException e) {
  // TODO 自動生成された catch ブロック
  e.printStackTrace();
}

ようするにソース上の文字列上の場所を探してきて、

IJavaElement[] elements = unit.codeSelect(start, length);

としてIJavaElement?を生成してるわけですね。。これだと、びみょーに他のクラスを取得してしまう可能性があるような。。別パッケージの同じ名前のクラスとかですね。。あーそのための戻り値が配列なんですかね。。*1

あるソースコードに書かれているクラス名を全て取得する

elementは ICompilationUnit? です。

try {
  IType[] types = element.getTypes();
  for (IType type : types) {
    logger.debug("Types[i]: " + type.getElementName());
  }
} catch (JavaModelException e) {
  // TODO 自動生成された catch ブロック
  e.printStackTrace();
}

これでそのソースコードに書かれているクラスのクラス名をすべて取得することができます。たとえばpublicなクラスの他にもクラスを定義している場合などですね。インナークラスは出てこないようです。


この記事は

選択肢 投票
おもしろかった 5  
そうでもない 0  

現在のアクセス:9993


*1 そもそもこのメソッドはエディタ上で選択してる単語名なクラスをひいてくるなんて用途に使われてるんでしょう

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2021-12-14 (火) 11:38:56 (861d)