Edited at

【Eclipse】ExecutionEventオブジェクトからICompilationUnitオブジェクトを生成する方法

More than 3 years have passed since last update.

ICompilationUnitオブジェクトはJavaソースファイル一つを表すオブジェクトであり、ASTを構築するときに必要となる。ASTを構築すれば、Javaソース内の情報の取得・操作が直感的に行えるため便利である。

イベントハンドラで受け取るExecutionEventオブジェクトから、イベント発生時の編集対象であるJavaソースファイルのICompilationUnitオブジェクトを生成する方法について書き残す。現時点で3通りの方法を見つけている。


最も直感的な方法


  1. アクティブなエディタの編集対象を取得

  2. 編集対象のファイルを取得

  3. ファイルからJavaソースのオブジェクトを生成

// インポート宣言

import java.util.Optional;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.handlers.HandlerUtil;

// メソッド定義
public Object execute(ExecutionEvent e) throws ExecutionException {
ICompilationUnit source = Optional.of(e)
.map(HandlerUtil::getActiveEditorInput)
.map(input -> (IFileEditorInput)input)
.map(input -> input.getFile())
.map(JavaCore::createCompilationUnitFrom)
.orElse(null);

return null;
}


  • エディタの編集対象がファイル以外の場合、HandlerUtil.getActiveEditorInputメソッドの戻り値はIFileEditorInputオブジェクトではないので、ダウンキャスト時に例外が発生する。

  • エディタの編集対象がJavaソースファイル以外のテキストファイルである場合、JavaCore.createCompilationUnitFromメソッドで例外が発生する。


  • IFileEditorInputインターフェースの依存プラグインは、org.eclipse.uiではなくorg.eclipse.ui.ideなので注意。


アダプタを利用した方法その1


  1. アクティブなエディタの編集対象を取得

  2. 編集対象のオブジェクトに、ファイルオブジェクトを下さいと頼む

  3. 受け取ったファイルオブジェクトから、Javaソースのオブジェクトを生成

// インポート宣言

import java.util.Optional;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.ui.handlers.HandlerUtil;

// メソッド定義
public Object execute(ExecutionEvent e) throws ExecutionException {
ICompilationUnit source = Optional.of(e)
.map(HandlerUtil::getActiveEditorInput)
.map(input -> input.getAdapter(IFile.class))
.map(JavaCore::createCompilationUnitFrom)
.orElse(null);

return null;
}


  • エディタの編集対象がファイル以外の場合でも、input.getAdapter(IFile.class)の戻り値がnullとなるだけで、特に例外は発生せず処理が終了する(source変数にnullが入る)。

  • エディタの編集対象がJavaソースファイル以外のテキストファイルである場合、Javaソースのオブジェクト生成時に例外が発生する。


アダプタを利用した方法その2


  1. アクティブなエディタの編集対象を取得

  2. 編集対象のオブジェクトに、Java要素を下さいと頼む

  3. 受け取ったJava要素はJavaソースのオブジェクトなのでダウンキャスト

// インポート宣言

import java.util.Optional;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.ui.handlers.HandlerUtil;

// メソッド定義
public Object execute(ExecutionEvent e) throws ExecutionException {
ICompilationUnit source = Optional.of(e)
.map(HandlerUtil::getActiveEditorInput)
.map(input -> (ICompilationUnit)input.getAdapter(IJavaElement.class))
.orElse(null);

return null;
}


  • エディタの編集対象がファイル以外であっても、Javaソースファイル以外のテキストファイルであっても、input.getAdapter(IJavaElement.class)の戻り値がnullとなるだけで、特に例外は発生せず処理が終了する(source変数にnullが入る)。


  • input.getAdapter(IJavaElement.class)の戻り値がICompilationUnitオブジェクト以外の場合は例外が発生するが、戻り値がICompilationUnitオブジェクト以外ということは多分ない…と思う。