Top / Eclipse / プラグイン開発のTIPS集 / コード解析 / org.eclipse.text.edits.MultiTextEdit

org.eclipse.text.edits.MultiTextEdit?クラスはエディタで文字列を挿入するなど、ソースコードを編集するための機構です。この機能を用いて、指定したメソッドにアノテーションを加えるとか、Getter/Setterを追加するとかのプラグインを開発することができそうです。

やってみる

実際にやってみます。スケルトンとなるコードはだいたい以下の通りです。引数のICompilationUnit?*1 内にクラスが(場合によっては複数)定義されていたとして、そのクラスのメソッドにだけ hoge って文字を挿入するサンプルです。

private void execute(ICompilationUnit unit, IProgressMonitor monitor) throws CoreException {
  IJavaElement[] elements = null;
  try {
    if (!unit.isStructureKnown()) {
      elements = unit.getChildren();
    }
  } catch (JavaModelException e) {
    e.printStackTrace();
  }
  try {
    monitor.beginTask("タスク実行。", 5);

    // ITextFileBufferManagerの取得。
    ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
    IPath path = unit.getPath();
    // ファイルにconnect
    SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 4);
    subMonitor.beginTask("", elements.length);

    manager.connect(path, LocationKind.IFILE, subMonitor);
    try {
      // document取得。
      IDocument document = manager.getTextFileBuffer(path,
          LocationKind.IFILE).getDocument();
      IJavaProject project = unit.getJavaProject();

      // エディット用クラスを生成。
      MultiTextEdit edit = new MultiTextEdit();

      // 子要素は、パッケージ宣言だったり、クラスだったりする。一つのソースに複数クラスが書いてある場合もあるし。
      for (final IJavaElement javaElement : elements) {
        // ↓型(クラス)だったらば、ITypeにキャストしていい。
        if (javaElement.getElementType() == IJavaElement.TYPE) {
          IType type = (IType) javaElement;
          // メソッド一覧を取得。
          IMethod[] methods = type.getMethods();
          for (IMethod lastMethod : methods) {
            String code = createIndentedCode("hoge",lastMethod, document, project);

            // オフセット位置を計算する。
            int memberStartOffset = getMemberStartOffset(lastMethod, document);

            // オフセット位置に、挿入する。
            edit.addChild(new InsertEdit(memberStartOffset,code));
          }
        }
        subMonitor.worked(1);
      }
      edit.apply(document); // apply all edits
    } catch (BadLocationException e) {
      e.printStackTrace();
    } finally {
      manager.disconnect(path, LocationKind.IFILE, subMonitor);
      subMonitor.done();
    }
  } finally {
    monitor.worked(1);
    monitor.done();
  }
}

挿入する位置を求めるためになんか色々やってますが、

// ITextFileBufferManagerの取得。
ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
IPath path = unit.getPath();
manager.connect(path, LocationKind.IFILE, subMonitor);
try {
  // document取得。
  IDocument document = manager.getTextFileBuffer(path,LocationKind.IFILE).getDocument();
  IJavaProject project = unit.getJavaProject();
  // エディット用クラスを生成。
  MultiTextEdit edit = new MultiTextEdit();
  edit.addChild(new InsertEdit(memberStartOffset,code)); //offsetの位置に、codeを挿入。
  edit.apply(document); // apply all edits
} catch (BadLocationException e) {
  e.printStackTrace();
} finally {
  manager.disconnect(path, LocationKind.IFILE, subMonitor);
}

このように ITextFileBufferManager? インタフェースでソースコードに接続してIDocument を取得、MultiTextEdit? クラスで修正するコードを生成してapplyメソッドで反映、って流れになってると思えば良さそうです。


この記事は

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

Top / Eclipse / プラグイン開発のTIPS集 / コード解析 / org.eclipse.text.edits.MultiTextEdit

現在のアクセス:6967


*1 ソースファイル一個って事でいい

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS