2009年1月13日火曜日

AIR GEARにデバッグ実行を組み込み中

AIR GEARにデバッグ実行を組み込み中です。
いやぁ〜色々詰まって大変ですけど、ちょっとづつ進展していってます。
AdobeAIRのfdbというコマンドを使って、EclipseのGUIとつなげていく作業しています。
fdbはFlexSDKのbinの中に入っています。コマンドはこんなのがあります。

fdbはいいとして、EclipseのPluginの方が難しい〜!調査するのに時間かかる〜!
解決して行った事を記事に書こうと思ってはいるんですが、同じような事をしたい人ってあまりいないですよね...記事にして意味あるのかは不明ですね...(笑)
ですが、今の段階のものをメモしておきます。


Launcherにてデバッグ実行を指定
org.eclipse.debug.core.launchConfigurationTypesの拡張ポイントのLauncherにてmodes属性にdebugを追加します
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
delegate="net.sf.amateras.air.launch.LaunchAIRConfiguration"
id="net.sf.amateras.air.launchAIRConfigurationType"
modes="run, debug"
name="AIR Application"
public="true">
</launchConfigurationType>
</extension>


デバッグ実行を行なうと、LaunchConfigurationDelegateで実装する以下のメソッド
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch,
IProgressMonitor monitor) throws CoreException
の mode の値が ILaunchManager.DEBUG_MODE の値になってきます。
これで条件分けして普通の実行と、デバッグ実行とで処理を分けて実装していきます。

AIR GEARでは以下の感じで実装。
if (mode.equals(ILaunchManager.DEBUG_MODE)) {
FdbShell fdb = new FdbShell();
fdb.start();
IDebugTarget debugTarget = new AirDebugTarget(launch, fdb, target);
launch.addDebugTarget(debugTarget);

} else {
File executeFile = new File(sdkPath, adlpath);
String[] command = new String[] { target };
Process process = ProcessUtil.createProcess(executeFile, command, null);
DebugPlugin.newProcess(launch, process, "\"" + executeFile.getName() + " "
+ new File(command[0]).getName());
}

デバッグ実行のコードでは、org.eclipse.debug.core.model.IDebugTarget を実装したクラスを作成していく必要があります。


IDebugTarget
この、DebugTargetの実装については長くなってしまうので詳しくはまた別途記事にするとして、概要だけ。
JavaでEclipseのデバッグ実行をして、DebugPerspectiveを表示すると実行中ThreadなどがTree形式で見えますよね? あれのRoot要素です。
IDebugTarget
|__ IThread
|__ IStackFrame

こんな感じの親子階層になっていて、このそれぞれの実装をしていく感じになります。
Stepover,Stepintoなどのデバッグ時に操作するコマンドの実装はこれらのクラスにて実装していきます。


Breakpoint
Breakpointの場所の指定は、エディタ上でBreakpointのマーカーで表示させたいですよね。Javaプログラムの時のように。
これが、結構大変。。。苦労しました。これも概要だけを少し。
まずはBreakpoint用のマーカーを登録します。拡張ポイントはorg.eclipse.core.resources.markers。
org.eclipse.ui.ide.markerImageProvidersの拡張ポイントにてマーカーのイメージを設定。
マーカーのattributeにMapが指定できて、このMapのKeyに
IMarker.MESSAGE
IBreakpoint.ID
IBreakpoint.PERSISTED
IBreakpoint.ENABLED
IBreakpoint.REGISTERED
を指定して使っていきます。
ちなみに、PERSISTEDにtrueしてみてるんですが、永続化できてない。。これはまたソースを探って見てみる予定。

Breakpointは、org.eclipse.debug.core.breakpointsの拡張ポイント。
登録したマーカーを作成するには IResource#createMarker({マーカーのID}) で。
Breakpointは、DebugPlugin.getDefault().getBreakpointManager()にて管理しているので、作成したものはここに登録する。

エディタの行の部分をダブルクリックでBreakpointを付けたり、消したりする場合には、org.eclipse.ui.editorActionsの拡張ポイントに、RulerActionを登録。
Actionクラスはorg.eclipse.ui.texteditor.AbstractRulerActionDelegateを実装したものを用意する。
actionノードのactionID属性にて"RulerDoubleClick"を指定すると、マウスのダブルクリックが有効になるっぽいです。

右クリックのポップアップメニューにAdd Breakpointなどのメニューを出したい場合には、org.eclipse.ui.popupMenusに登録してあげる必要があります。ここで、継承元にするクラスは、org.eclipse.ui.texteditor.AbstractRulerActionDelegate。


SourceLocater
Breakpointで停止した場合や、Stepover,Stepintoなどで停止した場合、該当のソースコードを表示して、止まっている行が反転するようにしたい...時にはSourceLocaterの実装が必要になります。

拡張ポイントはorg.eclipse.debug.core.sourcePathComputersと、org.eclipse.debug.core.sourceLocators。
前者はソースのContainerを判定するもので、org.eclipse.core.resources.IContainerの配列を返す という役割をします。
例えばLuncherの情報から該当のProjectを取得し、org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainerを使用するようにしたり...します。
後者のsourceLocatorsは、ソースファイルを発見し、IEditorInputを返す という役割をします。

これらのSourceLocaterはLaunchのlaunchConfigurationTypeの設定にて、sourceLocatorId、sourcePathComputerIdという属性で関連づけします。


ということで、Breakpointの場所で止まって、ソースが表示されて...という所までなんとか出来るようになりました。
ただ、”正しい手順”でしないとまだ上手く動かない所もあるし、まだ実装したい所も多いので、リリースできそうなものにするのは時間がかかりそうですが...デバッグ実行できたら便利と思うので、諦めずに頑張ってみます〜

おーし、明日は、変数の値表示の所をやってみるぞぅ。
• • •