Transcript レイヤー機構付きIDE
数理・計算科学専攻
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