統合開発環境のための プログラミング言語拡張

統合開発環境のための
プログラミング言語拡張
フレームワーク
理学部 情報科学科
05_22951 松本 久志
指導教員 千葉滋
言語拡張システムの必要性

言語拡張を容易にするためのシステム
◦ ドメイン固有言語の作成
 例 : O/Rマッピング
◦ 既存言語の補填
 例 : Open class

@Refines(A.class)
class B {
void hoge() { .. }
}
コンパイラのためのシステム
◦ Polyglot [Myers ら ‘2003]
◦ JastAdd [Hedin ら ‘2003]
統合開発環境のための
言語拡張システム

統合開発環境への対応
◦ 現在ではコンパイラの
提供だけでは不十分

従来技術 Polyglot, JastAdd など
◦ 編集時の支援がない
 対話的なエラー報告
 Eclipseでは編集時に専用の処理
提案 : 編集時のエラー出力を操作する
メタオブジェクトプロトコル(MOP)

言語拡張をメタオブジェクトで記述

編集時とコンパイル時の2つのMOP
◦ 編集時メタオブジェクト
 編集時に出力するエラーを制御
◦ コンパイル時メタオブジェクト
 ソースコード変換で言語拡張を実装
編集時のMOPの動作

エラーの出力を操作
◦ 必要のないエラーを除去
◦ 新たに必要なエラーを追加

ソース変換は行わない
◦ 厳密なエラー解析はコンパイル時に行えば良い
@Refines(A.class)
class B {
void hoge() { .. }
}
@Refines(A.class)
class B {
void hoge() { .. }
}
class A {}
class A {}
コンパイル時のMOPの動作

拡張言語のソースコードを変換
◦ 文字列としての変換
◦ ASTを利用した変換
 元の言語の構文解析器を用いてASTを生成

変換後既存のコンパイラでコンパイル
@Refines(A.class)
class B {
void hoge() { .. }
}
class A {}
class A {
void hoge() { .. }
}
実装

EclipseのJava開発環境を拡張可能に
◦ JDTプラグインを拡張

言語拡張者の作業
 メタオブジェクトのメソッドを上書き
◦ 編集時: finalizeProblems
エラー出力の操作
 引数:ソースファイルの解析結果
 標準JDTが作成、発見したエラー情報を含む
◦ コンパイル時: convertSources
 抽象構文木を取り出し変形
ソースの変換
適用例
@Refinesによるopen classの機構

言語拡張に由来した
エラーの除去

拡張された言語の
コンパイル及び
実行が可能

エラー操作は18行
ソース変換は32行
の記述で実現
記述例
@Refinesによるopen classの機構
編集時のエラー出力の操作
コンパイル時のソース変換
@Override
@Override
public void convertSources() {
public void finalizeProblems(CompilationUnitDeclaration u) {
for(CTUnit unit : CTMOP.getUnits()) {
List<CategorizedProblem> newList
/* ビジターパターンを用いて
= new LinkedList<CategorizedProblem>();
CompilationResult result = u.compilationResult();
@Refinesアノテーションを検索 */
unit.getCompilationUnit().accept(new ASTVisitor() {
for(CategorizedProblem problem : result.problems){
public boolean visit(SingleMemberAnnotation node) {
if(problem.isError()) {
if(node.getTypeName().toString().equals(“Refines”)
if(problem.getCategoryID() ==
CategorizedProblem.CAT_TYPE) {
&& node.getParent() instanceof TypeDeclaration) {
// @Refinesアノテーションに関するエラーは無視
: // フィールド及びメソッドのコピー
if(problem.getArguments()[0].equals(“Refines”)) continue;
}
}
}
: // 他のエラー判定条件
}
newList.add(problem);
}
}
}
}
unit.compilationResult().problems
= newList.toArray(new CategorizedProblem[newList.size()]);
}
関連研究

拡張可能コンパイラ
◦ Polyglot [Myers ら ‘2003]
 拡張しやすいJavaフロントエンドフレームワーク
◦ JastAdd [Hedin ら ‘2003]
 属性文法による意味解析
 差分のみの記述で構文拡張可能

編集時メタオブジェクト
◦ “Expressive programs through presentation extension”
[Eisenberg ら ‘2007]
 編集時とコンパイル時のMOPを提供
 編集時のソースコードの表示を制御
まとめと今後の課題

統合開発環境に対応した
言語拡張フレームワークの提案
◦ コンパイル時及び編集時のMOPを提供
 編集時にエラー出力の操作を行う
 コンパイル時にソース変換を行う
◦ JDTを拡張して実装

今後の課題
◦ ASTの操作の簡易化
◦ エラーの判別方法の確立