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