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

概要

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

2009/07/01追記:Javaのソースコードに関していえば、JDTの強力な機能を使えばこの機構は不要かもしれません。あくまでJavaのモデルを意識しないようなテキスト編集に用いるのが良いのかも。。。type.createMethodとか使えば、ソースの最後にメソッドを追加するとかできるようだし。。。

やってみる

実際にやってみます。スケルトンとなるコードはだいたい以下の通りです。引数の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 method : methods) {   (↓色々やってますが、割愛)
            String code = createIndentedCode("hoge",method, document, project);

            // オフセット位置を計算する。(↓色々やってますが、割愛)
            int memberStartOffset = getMemberStartOffset(method, 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(offset,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メソッドで反映、って流れになってると思えば良さそうです。


この記事は

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

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

現在のアクセス:6957


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

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