数理・計算科学専攻 09M37287 松本 久志 指導教員 千葉 滋 1 既存のプログラムに対して差分を記述することで 新しいプログラムの開発を行う ◦ 仕様の類似したソフトウェアの開発 組み込みソフトウェア開発 パッケージソフトウェアの複数エディション フリーソフト版とシェアウェア版の差別化 ◦ デバッグ用コードの挿入・除去 2 C/C++のプリプロセス命令 ◦ #defineにより差分記述が可能 ◦ ソースコード中に直接記述 行単位での任意の差分記述が可能 問題点 ◦ ◦ ◦ ◦ 可読性の低下 コード変更の必要性 ある差分に関連するコードの抽出が困難 他の言語への導入が困難 構文解析器の拡張が必要 #define SYNC // #define LOG static void run() { Hoge h = new Hoge(); #ifdef SYNC synchronized(lock) { #endif #ifdef LOG System.out.println(“run”); #endif h.run(); #ifdef SYNC } #endif } Javaに#ifdef/#endifを 導入した仮想言語 3 差分を自由にon/off可能 ◦ コンパイル時の適用・非適用 ◦ 編集時の表示・非表示 ◦ コードを変更しない ある差分に関連するコードをまとめて扱う ◦ 関連コードの抽出 ◦ リファクタリング 既存のIDEの拡張が容易 ◦ 既存のエディターやコンパイラを流用 4 #define SYNC // #define LOG static void run() { Hoge h = new Hoge(); #ifdef SYNC synchronized(lock) { #endif #ifdef LOG System.out.println(“run”); #endif h.run(); #ifdef SYNC } #endif } レイヤーとは ◦ 差分に関連するソースコード断片 IDE上でまとめて操作可能 レイヤーごとの表示・非表示(エディター) レイヤーごとの適用・非適用(コンパイラ) ベースとなるプログラム ログ出力に関するコード 同期に関するコード static void run() { Hoge h = new Hoge(); synchronized(lock) { System.out.print(“run”); h.run(); } } 5 ソースファイル内ではプリプロセス命令により注釈 ◦ レイヤーの選択状況と併せてIDEが解釈 ◦ エディター上にはIDEが解釈したソースコードを表示 ソースファイル static void run() { Hoge h = new Hoge(); #ifdef SYNC synchronized(lock) { #endif #ifdef LOG System.out.println(“run”); #endif h.run(); #ifdef SYNC } #endif } 解釈されたソースコード レイヤーの 選択状況 ○ ベースレイヤー × ログレイヤー static void run() { Hoge h = new Hoge(); synchronized(lock) { h.run(); } ○ 同期レイヤー } 6 レイヤーのon/offの切り替え ◦ エディター上での表示・非表示 ◦ コンパイル時の適用・非適用 ◦ レイヤーの状態はIDEが保持 static void run() { Hoge h = new Hoge(); synchronized(lock) { System.out.print(“run”); h.run(); } } ログ・同期両方の レイヤーを適用 static void run() { Hoge h = new Hoge(); synchronized(lock) { h.run(); } } ログレイヤーのみ適用 static void run() { Hoge h = new Hoge(); h.run(); } ログ・同期両方の レイヤーを非適用 7 指定したレイヤーの着色 ◦ 背景色を変更 ◦ 差分に関連するコードを視覚的に抽出可能 static void run() { Hoge h = new Hoge(); synchronized(lock) { System.out.print(“run”); h.run(); } } static void run() { Hoge h = new Hoge(); synchronized(lock) { System.out.print(“run”); h.run(); } } static void run() { Hoge h = new Hoge(); synchronized(lock) { System.out.print(“run”); h.run(); } } ベースレイヤーを選択 ログレイヤーを選択 同期レイヤーを選択 8 ソースコードをプリプロセッサにより変換 ◦ 変換したコードをエディターやコンパイラへ 既存のエディターやコンパイラを流用可能 9 対象言語 ◦ Java + #ifdef/#endif Eclipseプラグイン ◦ ビュー レイヤーの操作 ◦ エディター プリプロセス命令を解釈して表示 ◦ ビルダー プリプロセス命令を解釈してコンパイル 10 レイヤーの操作を統括して行う ◦ ◦ ◦ ◦ レイヤーの表示 レイヤーの作成・削除・統合 レイヤーのon/off 着色するレイヤーの選択 レイヤー状態の変化を通知 ◦ エディターの表示を変更 ◦ 自動および手動でコンパイル 11 レイヤー状態を反映して表示 ◦ コードの折りたたみによりコードの非表示を表現 差分の存在を示す ◦ プリプロセス命令は灰色で表示 可読性の低下を防ぐ 12 クラスファイルの生成 ◦ 自動ビルド ソースファイルの保存時 レイヤー構成の変更時 ◦ プリプロセッサ処理後JDTのコンパイラに処理を委譲 既存のコンパイラの流用 13 LayerIDEを用いて差分記述を行った ◦ GUI・CUIの切り替え ぷよぷよ(パズルゲーム)の連鎖シミュレーター ◦ コア部分およびGUI・CUI・LOGの3つのレイヤーで構成 引数からフィールドを生成し、 連鎖をシミュレート コア部分 状態などのログを出力 シミュレートした連鎖を グラフィカルに表示 シミュレートした連鎖を コンソールに表示 GUI差分 LOG差分 CUI差分 14 ファイルの読み込み後に変換 ◦ エディターは新たに作成 ◦ ビルダーは流用可能 想定していた実装 実際の実装 拡張ポイントによる 処理の追加が困難 15 AspectJ [Kiczalesら ‘2001] ◦ アスペクト指向言語 横断的関心事をモジュール化 差分を横断的関心事として捉える ◦ メソッド単位より細かい粒度の改変が困難 ◦ コンパイラの拡張が必要 Colored IDE [Kästner ら ‘2008] ◦ Eclipseプラグイン ◦ ASTに対してFeatureを関連付ける エディタ上では色を付けて表示 言語に依存する 完全な形のASTが存在する必要がある 16 レイヤー機構付きIDEの提案 ◦ レイヤーとは 差分に関連するコードをIDE上でまとめたもの ◦ IDE上で差分を操作可能 編集時の表示・非表示 コンパイル時の適用・非適用 レイヤーの着色 LayerIDEの実装 ◦ Eclipseプラグイン Java + #ifdef/#endif 17
© Copyright 2024 ExpyDoc