日本ソフトウェア科学会第 30 回大会 (2013 年度) 講演論文集

変数参照関係を用いた関数型プログラムのコードリー
ディング支援
遠藤 誠典

百足 勇人

森畑 明昌

上野 雄大

大堀 淳

既存のプログラムを再利用したり，複数人でプログラムを開発したりする場合に，コードを読んで内容を理解しなければならない場面がある．コードを読む際には，検索などをして理解の補助ができることが望ましい．しかし，同じ
名前の変数が複数定義されていたり，プログラムが複数のファイルに分かれていたりすると，変数や関数がどの定義のものを参照しているのかを追うことは単純な検索では難しい．また，関数やモジュールがどのような処理をしているか，ということがおおまかに分かればコードの理解の助けになる．以上を踏まえて関数型プログラムのコードリー
ディング支援のためのツールを作った．このシステムは変数の参照位置から正確な定義位置を検索することができる．加えて，変数や関数の依存関係をもとにファイル間の依存関係を提示できる．これはモジュールのおおまかな振る舞いを把握するのに有用である．

コードの理解には，ユーザが付けた種々の名前の種類

1 はじめにとその参照関係を読み解く作業が必要である．

既にあるプログラムの利用や，複数人によるプロ

さらにプログラミング言語のソースコードの場合，グラムの開発といった場面では，既存のプログラムの同一の単純な名前が異なる目的で多数存在するといっ構造や動作を理解する必要がある．プログラムの作たことがよくあり，大規模なソースコードにおける名者が，何らかの文章で説明を行ってくれている場合も前の参照関係を正確に読み解く作業は，困難なものある．しかし，その説明がプログラムをより詳細に理となる．この問題に対処するための，プログラムを構解するには不十分であったり，そもそも用意されてな

造を持たないテキストみなし，文字列検索ツールをかったりといったことがある．そういった時には，プ用いることがよく行われている．しかし，名前を定義

ログラムのソースコードを読み，その中身を理解するすることによって静的なブロック構造を実現している

必要が出てくる．

言語では，文字列検索によって正確な参照関係を特定読む対象となるソースコードは，変数や関数，デー

することは困難である．さらに，多量のソースファイ

タ型，構造体などの種々の要素を用いて行う計算の記ルを読み解く必要がある大規模なシステムでは，そ述である．プログラミング言語が実現するそれら構造

れらファイル間の参照関係や依存関係が不明のため，の意味を抽象し，構文としての構造に着目するなら

名前の検索さえ困難である場合が多い．これら問題

ば，プログラミング言語で書かれたソースコードは，に対処するためには，ソースコード中の名前の種類

種々の種類の要素に対してユーザーが自由に名前をや対応する定義位置を正確に特定し，さらに，それつけ，それら名前を参照しながら，複雑な構造を記述

ら参照関係によって生じるソースファイルの依存関係していく文書と捉えることができる．従って，ソースを表示する系統的な支援ツールがあるのが望ましい．

Code Reading Assistance for Functional Programming based on Variable Def-use Relationships
Masanori Endo，Yuto Mukade，Akimasa Morihata，Katsuhiro Ueno，Atsushi Ohori, 東北大学, Tohoku
University.

本研究の目的は，関数型プログラムに対して，この両者の機能をもつコードリーディング支援ツールを開発することである．
名前の正確な参照関係の特定を支援するコードリー

ディング支援ツールの構築は，プログラム構造の静的な分析に基づく名前の定義と参照に関する情報を抽2 関数型言語の名前の参照構造

出する必要がある．第 5 節で概観する通り，コード

現在，プログラムに登場する変数などの要素に名前

リーディング支援ツールの実装では，それぞれのツーを与え，その名前を用いてプログラム構造を表現する

ルにとって必要な情報を取り出すための独自の解析器

言語は多数存在している．Standard ML は，その中を構築するアプローチが多い．しかし，それには大変

でも言語と一体となったモジュールシステムを備えたな手間がかかり，分析された結果が正しいかというこ

代表的な言語の１つである．

とを確かめるのも困難である．この問題は，コンパイ

ここからの話を進めるにあたって，対象となるプロラが持つ名前の参照関係の分析機能が利用できれば，グラミング言語を具体的に設定しなければならない．

完全に解決することができる．コンパイラは，すべてそこで，今回は SML#を対象としている．SML#は，の名前について，その定義位置と種類，さらにその名Standard ML を拡張し，分割コンパイル機能などを前の正確な参照関係を把握している．以上の洞察に基備えた関数型プログラミング言語である．

づき，本研究では，コードリーディング支援ツールの構築を，以下の 2 段階で行う戦略をとる．

1. コンパイラを改良し，すべての名前に関して，その定義位置と種類，名前の参照とそれに対応

SML#で書かれたコードの中で名前が与えられて登場するものは，ローカルに定義される変数だけではない．以下のような種類の名前が登場してくる．

• プログラム変数

する定義の関係をデータ構造として取り出す．こ– ローカル変数 val x = 1 における x など．

れは，コンパイラがソースコードを解析する際，– 関数の仮引数名 fun f x = 1 における x

コンパイラが行う名前の定義の認識と参照の認識を，それぞれ事象としてトレースすることで取り出すことができる．

2. とり出された名前の定義と参照情報データを，
コードリーディングに有用な情報に変換し，ユー
ザに提示する．有用な情報やその提示方法には，種々の可能性があるが，本研究では，コードリー
ディング支援ツール構築の最初の段階として，エディタでの名前の参照位置から定義位置へのジャなど．

– 例 外 名 exception x of int に お け る xなど．

– コンストラクタ名 datatype foo = A ofint における A など．
• ス ト ラ ク チャ名 structure S = struct ...
end における S など．
• ファンクタ名 functor F (..)

= struct ...

end における F など．

ンプ機能，および，名前の参照関係から生じる• 型コンストラクタ名 datatype foo = A of int

ファイルの依存関係グラフの表示機能を実現する．

における foo など．int などの組込み型も型コ

本節に続き本論文の構造は以下のとおりである．第 2
節では，本研究が対象とするソース言語の名前構造を概観し，名前の参照関係の解決に関する課題を論じる．第 3 節では，本研究で構築を目指すコードリー
ディイング支援ツールの実現のための戦略と具体的な

ンストラクタ名である．

• 型変数 datatype ’a foo = A of ’a における’a など．
• シグネチャ名 signature S = sig ...

end における S など．

方式を提示する．第 4 節では，開発したツールの実

ローカル変数は，その定義が有効な範囲で利用できる装の詳細を記述する．第 5 節では，今後の課題と既変数を定義する．関数の仮引数は，その関数が取る引存研究との関連を論じる．第 6 節は結論である．

数を関数中で扱うために関数の中でのみ有効な名前を引数に与えている．例外名は，ユーザーが定義する例
外に与えられ，ソースコード中にて自由に rise させることができ，例外を発生させる．コンストラクタ名

は，データ型が持つバリアントに与えられる名前であを用いた高度な構造で現していることがわかる．今回る．ストラクチャ名はストラクチャに与える名前であの名前の参照関係を分析するという問題を考えている．ストラクチャにアクセスする際に使われる．ファく上で最適な言語の 1 つだと考えられる．

ンクタ名はファンクタに与える名前である．ファンク
タは渡された値を使ってストラクチャを生成する．型

3 コードリーディング支援機能構築戦略

コンストラクタ名は，データ型に与えられる名前で，第 1 節で述べた通り，本研究では，コードリーディ

コンストラクタ名を値の先頭に持つようなものの持

ング支援ツールの構築を，つ型の名前である．型変数は，データ型や型の定義に

1. 名前間の正確な参照関係の分析と収集，任意の型を含む際にその型を表すものとして与えら

2. 参照関係を用いたコードリーディング支援機能れる名前である．シグネチャ名は，ストラクチャに適用するシグネチャにつける名前である．
これらに与える名前は，一つ一つが書き手であるの提供の２段階で構築する戦略を取る．本節では，それぞれの方式を提示する．

ユーザーが自由に決めることができ，自由にソース
コード中に登場させることができる．例えば，ローカ

3. 1 名前間の正確な参照関係の分析と収集

ル変数 x を定義した後に仮引数 x を含む関数を定義

第 2 節で詳述した通り，Standard ML は，型構成

し，さらに続けて先に定義したローカル変数 x を用子やプログラム変数を含む複数のカテゴリーに分類さいて計算を行うことができる．この時，SML#ではれた種々の名前によってプログラム構造を構築していローカル変数 x と仮引数 x はそれぞれ異なるものとる．さらに，SML#が提供する分割コンパイル機能して扱われ，互いに干渉することはない．名前としによって，それら名前は，プログラムが定義する内部ては 2 つとも x という同じ名前を与えられているが，名と，インターフェイスファイルを通じて参照される

実際は別物なのである．正確な変数参照関係を得るた

外部名に分割されている．本研究の最初の仕事は，こめにはこの 2 つの名前を見分けなければならない．

れら複雑な名前構造の分析を行い，全ての名前に関す

また，SML#は前述のように分割コンパイル機能

る情報を収集し，コードリーディング支援ツールで利を備えている．そのため，1 つのコンパイル単位を独用可能な形のデータ構造として構築することである．

立してコンパイルでき，異なるコンパイル単位の間でプログラム中に現れる名前に関して，分析し収集すの名前の利用が可能となっている．この時 SML#でべき情報は以下の通りである．

は，それぞれを独立してコンパイルするために，ソー

1. その名前出現の位置

スコードファイルに対応するインターフェイスファイ

2. 名前の属するカテゴリ

ルを参照することで，これを実現している．このイン

3. 名前が定義出現か参照出現かの別

ターフェイスファイルには，利用可能な名前が記述さ4. 参照出現に対して，その名前の定義位置れており，名付けられたものの種類によって名前とと

これら情報の特定は，プログラムの静的スコープのもにいくらかの情報も記述されている．このインター把握とスコープ内で定義されるデータ型の定義情報

フェイスファイルに記述されている名前とそれに伴うの解析を含むプログラムの静的な解析を必要とする．

情報を元に，それぞれのコンパイル単位の独立した

例えば以下のコード断片をみてみよう．

コンパイルを実現している．一方で，同じコンパイル

fun f x = x

単位の中にある名前の利用は，インターフェイスファ

この構文から，f は関数名の定義出現であることがわ

イルを経由することなく行える．ここでコンパイル単かるが，x が関数の引数定義であるか否かは，この関位の内部と外部で，名前の参照の方法が異なっている数の出現文脈に依存する．例えば，出現文脈にことに注意しなければならない．
これらのことから SML#はプログラム構造を名前

datatype foo = xなる定義があれば，x はデータ型 foo のコンストラク

タ x を参照する参照出現である．本研究では，コン

既に述べたように，ある変数参照に対してその定義

パイラはこれら情報をすべてて正確に解析しコンパを知りたい場合，名前をそのまま検索すると同じ名前

イルを行なっているという事実に着目し，コンパイラのもの全てが候補となってしまう．そのような場合，の静的解析機能を利用しこれら情報を収集するとい本当にこの参照に対する定義であるかということをう戦略を取る．

候補それぞれについて検討しなくてはならない．これ

本研究が基礎とする SML#コンパイラでは，名前に対し，もし正しい参照関係が得られているならば，の解析を行う機能が，NameEvaluation という一つの参照位置からこの定義位置を正確に探してくることフェーズに集約されているので，この収集が比較的容が可能である．

易に行われるはずである．NameEvaluation は，構文

この検索機能を，本研究では Emacs 上でのカーソ解析と糖衣構文の展開，型変数のスコープの決定の各

ルジャンプとして提供する．Emcas はソースコード

フェーズの後に起動され，以下の処理を行うコンパイ

エディタとして広く使われており，またユーザーによルフェーズである．

るカスタマイズが容易であるためジャンプ機能の新た

1. ユーザ定義のデータ型の解釈と型の生成な追加も用意であると予想される．また，定義の前後

2. 静的スコープを解析し名前の参照関係を決定

は，定義そのものではないが定義に関連するものが同する．

様に定義されている可能性が高い．そのため，カーソ

3. インターフェイスを通じた他モジュールの外部

ルジャンプによって定義の前後関係も同時に見ること

参照宣言と他モジュールからの参照のための外部ができるとソースコードをより理解しやすくなる．

名宣言の生成4. Standad ML のストラクチャ構造を解析し，ス

2 つめに，ファイル間の依存関係を提示することである．

トラクチャを持たないフラットな言語に変換する．

規模の大きなプログラムを開発する場合は，単一

5. Standard ML のファンクタを型宣言と関数宣のファイルにすべての内容が記述されることはなく，言に変換する．

モジュールごとにファイル単位で分割されていること

以上のように，NameEvaluation が上記の１から４のが殆どである．SML#においては，1 つのソースコー

機能を実現する過程で，我々が必要とする名前に関す

ドファイルに対して 1 つのモジュールを割り当てるる属性情報はすべて系統的に得られるはずである．最ことが多い．そのため，あるファイルが他のどのファ

後のファンクタのコンパイルは複雑な処理であるが，イルの資源を用いているかを調べることで，これら本研究が必要とする機能とはほぼ独立であり，その内モジュール間の連携の様子の概略を把握することが部構造の知識は重要ではない．

できる．ここでは，この関係を名前の参照関係から解

そこで，本研究の第一段階は，NameEvaluation

析し，ファイル間の依存関係として提示する．具体的フェーズを改良して，同フェーズが上記の１から４のには、この依存関係を，各ファイルをノード，各依存機能を実現する際に得られる情報を，本研究が必要

関係をエッジとした有向グラフとして表現し，ユーザとする形で取り出すことで達成できる．その詳細は，に視覚的に提示する．この機能は，巨大なプログラム

第 4 節で提示する．

の，複数のファイルからなる機能のかたまりを把握したり，さらにはプログラムの全体構造を大まかに理解

3. 2 コードリーディング支援機能の提供したりするのに役立つと考えられる．

名前の参照関係をユーザーに提示する際にその形というものは様々な可能性が考えられる．その様々な

4 実装の概要

可能性の中から今回はまず，次の 2 つのような形で我々は，以上の詳述した戦略と方式に従って，コー

ユーザーに提供することを考えていく．

1 つめは，参照位置からの定義位置の検索である．

ドリーディング支援ツールを開発中である．本稿では，現時点で実装を完了している本研究の第一段階の参照関係の分析と収集，および，それに基づき実現した２つのコードリーディング支援機能の実装の詳細を記述する．第 6 節で論じるとおり，本研究が提示したアプローチにより提供可能な情報は，本稿で報告する以外にも多数可能である．それらの実装を含むより体系的なコードリーディング支援システムを開発中であり，本稿に続く論文にて報告予定である．
第一段階の名前間の正確な参照関係の分析と収集
は，SML#コンパイラに対して以下の改良を加えることで実現した．

1. プログラム中の名前を，文字列ではなく，位置情報を含む以下の抽象データ型 symbol として表現する．

type symbol = {string:string, loc:loc}
type longsymbol = symbol list
loc はファイル名とファイル内の位置を表す型である．

2. 名前の登録と参照をすべて，ライブラリ関数を

図1

検索機能のスクリーンショット

通じて行うように変更する．静的解析は，プロ
グラム構造を表現する環境を維持することによっ

4. 1 テキストエディタ上での検索の実現て実現している．この環境を，symbol をキーと以上の改造により，コンパイラから参照関係の情報する辞書として表現し，さらに，プログラム中のが得られるようになった．次は，この参照関係を利用

名前の参照に対応する辞書の検索と名前の定義

した，参照位置から定義位置を検索する機能についてに対応する辞書への登録を，すべて，その他の目の実装を述べる．

的の辞書の検索や登録と区別し，専用のライブラ

図 1 は，Emcas 上で検索機能を実際に動かしていリ関数を通じて行うように変更した．

る様子である．以下，これを例とし，この検索機能を以上の変更によって，名前の定義に対する辞書登利用する際のユーザの操作の流れを述べる．ソース

録時に，登録内容と登録キーである symbol の位置情

コードファイルを a.sml とする．まず，a.sml を改

報から，名前の定義情報の属性をすべて得ることが造した SML#コンパイラに入力する．次に，Emacs

できるまた，名前の参照に対する辞書検索時に，検で a.sml を開く．そして，9 行目の変数 x の参照位置

索に使用されたキーの symbol の位置情報，検索結果の先頭にカーソルを合わせ，cursor-jump コマンドの辞書に登録登録内容とその辞書内のキーの symbolを実行する．これにより，新しいバッファ上に a.smlの位置情報から，それぞれ，名前の参照位置，名前のが新たに表示され，2 行目の変数 x の定義位置にカー

カテゴリ，その名前の定義位置情報を得ることができソルが移動する．

る．そこで，本研究では，SML#が NameEvaluation

以上のような流れは，コンパイラに加えるさらなフェーズを実行する時，以上の情報を，これらライブ

る改造と Emacs コマンドの実装によって実現されてラリ関数の呼び出しトレースとして出力することにいる．

よって，名前の定義情報リスト，及び名前の参照関係

前述のようなコンパイラの改造により，NameEval-

エントリのリストを出力するように SML#コンパイ

uation フェーズから名前についての種々の情報を得

ラを改造した．

ることができるようになっている．ここからさらに，

検索機能に適した形式で必要な情報だけを出力する．

コマンドの実装した．

具体的には，例えば以下の形式で参照関係を出力し検関連するツールとして，Ctags [1] というツールが索機能を実現している．以下これを TAG ファイルとある．このツールはソースコードファイルの集合を入呼ぶ．

力とし，TAGS ファイルというものを出力する．そし(setq tagsて，Emacs で入力したファイル集合に含まれるソー’(

スコードファイルを開き，コマンドを実行することで((7 . 8) . ("/sml/a.sml" . (3 . 8)))TAGS ファイルを利用したカーソルの移動が行われ((7 . 12) . ("/sml/a.sml" . (5 . 5)))

る．例えば，図 1 で示されている a.sml を Ctags に((9 . 8) . ("/sml/a.sml" . (2 . 4)))

入力し，同様に 9 行 8 列目にカーソルを合わせてコ))

マンドを実行する．その場合，Ctags の機能では始め上のものは，a.sml を改造を施した SML#コンパイに 2 行目にカーソルが移動する．続けてコマンドを実ラに入力し，出力された a.tag の中身である．

行すると 3 行目，9 行目と移動する．7 行目にカーソ

出力結果は，組の列からなる．それぞれの組は，参ルが移動しないことから，Ctags は文字列 x をを見つ

照位置と，それに対応する定義位置を表す．前者は，けてくるわけではなく，何らかの方法で a.sml を分

当該ソースコードファイル上での参照される名前の現析し，名前 x の定義位置に関する情報を TAGS ファ

れる行と列を表している．例えば (9 .

8) は 9 行 8

イルを出力していることが分かる．しかし，Ctags の列目の参照（ここでは b = x + 3 の x）を表す．後

TAGS ファイルは参照位置に関する情報は出力され者は，その変数を定義しているソースコードファイルていない．即ち，名前 x からその定義位置を探しての名前，そのファイル上での行と列を表している．以おり，名前 x が複数回定義されていた場合，どの定上のように，TAG ファイルには注目するソースコー

義が注目している参照位置に対する名前の定義なの

ドファイルに現れている全ての名前の参照関係をリス

かということは分からない．一方，今回我々が実装しトの形で持っていることになる．

た cursor-jump コマンドで用いている TAG ファイ

以上のような情報を NameEvaluation フェーズでルには，参照位置に対する定義位置が組で出力されて集めた情報から抽出し，a.sml に対しては a.tag といる．このため，ある参照位置からその正しい定義位

いう名前の TAG ファイルに出力するような改造を置を知ることができる．

SML#コンパイラに加えた．
次に，Emacs 上で TAG ファイルを利用し，参照位置からの定義位置の検索を実現するための cursor-jump
コマンドの実装を行う．まず，cursor-jump コマンド

4. 2 依存関係グラフ提示機能の実現
次に，ファイル間依存関係をグラフとして提示する機能の実装について述べる．

を実行することでソースコードファイル a.sml に対

4. 2. 1 グラフ作成システム実装の方針

応する TAG ファイル a.tag を開く．そして，現在の本論文では，プログラム中の名前の参照関係からファ

カーソル位置を取得し，a.tag から参照位置とカーソ

イル間依存関係グラフを作成するために，Graphviz [2]ル位置とが一致する要素を取り出してくる．例えば，というソフトウェアを用いる．Graphviz はグラフの9 行目の 8 列目にカーソル来ているのならば，((9 .

可視化を行うためのオープンソースのソフトウェア

4))) を取り出し

で，DOT 言語という言語でグラフの構造を記述した

8) .

("/sml/a.sml" .

(2 .

てくる．これから定義位置 ("/sml/a.sml" .

(2 .

4)) を取り出し，定義位置のファイル"/sml/a.sml"
を新しく作ったバッファに開く．最後に，新しく作ったバッファのカーソルを定義位置の行と列である 2 行

4 列目に移動させる．以上のような動作を行うようにものを，GIF や PNG などのフォーマットの画像ファイルに変換することができる．
以下，SML#コンパイラと Graphviz を用いて，依存関係グラフを表示するための戦略を示す．

1. 本節冒頭の改造により得られたコンパイラにさ記述することも可能である．さらに，4，5 行目のよac

うに，各ノードにはラベルを設定することができる．
デフォルトではノードの名称がそのまま表示されるが，ラベルを設定することにより，ラベルの名称で表示される．複数のノードを同じ名称で表記したい場

b

d

d

合などに用いる．ラベルを設定したノードからエッジを伸ばす場合は，ラベル名ではなく，ノード名を使っ

図2

グラフ sample1て指定する．

4. 2. 3 生成する DOT 言語コードの形式
らなる改造を加え，名前の参照関係エントリのリストから，入力ファイルが依存する他のファイル

依存関係のグラフを表現する DOT 言語コードの生成を考える．

名をすべて調べ上げ，これから 3. 2 節の設計に従

まず，コンパイラの改造によって得られた，名前のいファイルの依存関係グラフを構築し，これを表参照関係エントリのリストを解析し，参照先のファイ

現する DOT 言語コードを出力するようにする．

ル名が入力ファイル名と異なっているエントリをすべ

2. 依存関係を表示したい各ソースファイルをそれて抽出し，これにより，入力ファイルの依存している

ぞれ，1 で改造したシステムに与え，各ソース

ファイル名の集合を得る．ここで得られるファイル名

ファイルに対応する DOT 言語コードを出力さは，ソースファイルではなく，インターフェースファ

せる．

イルまたはシグネチャファイルの名前となる．第 2 節

3. 出力された DOT 言語コードを一つのコードで述べたように，SML#コンパイラはインターフェーにまとめ，Graphviz に与えることで，各ソース

スファイルによって分割コンパイル機能を実現しておファイル間の依存関係を表すグラフを生成する．

り，そのため外部ファイルから参照される名前はイン

4. 2. 2 DOT 言語によるグラフ表現

ターフェイスファイルによって提供されるものである

DOT 言語はテキストを用いてグラフを表現するたことに注意せよ．本システムの実装では，ソースファめのデータ記述言語である．DOT 言語は非常にシンイル間の依存関係グラフを作成するため，インター

プルな文法で記述される．以下に例を示す．

フェースファイル，例えば a.smi，に対しては，これdigraph sample1 {と拡張子以外同名のソースファイル a.sml が存在す

a -> b;ると仮定し，インターフェースファイルへの依存関係

c;をソースファイルへの依存関係と読み替えている．こd1 [label = "d"];のソースとインターフェースの対応と，それに関する

d2 [label = "d"];問題については第 5 節でさらに議論する．次に，置c -> d1;

き換えにより得られたソースファイル名のリストを用

c -> d2;

いて，依存関係グラフのノードとエッジの定義を行う}

DOT 言語コードを生成する．ノードの定義は，入力

この DOT 言語コードを Graphviz に与えると，図 2として与えたファイル自身と，それが依存するファイに示すグラフが描画される．

ルの集合すべてとする．エッジの定義は，始点が入力

1 行目のキーワード digraph は対象が有向グラフ
であることを表す．アルファベットや数字で構成されファイル，終点が依存するファイルとなるエッジすべてとする．

た名前はノードを表し，->はエッジを表す．2 行目の例えば入力ファイル a.sml に対し，b.smi と c.smi

ようにノードをエッジで接続したものを直接記述するが依存するファイルとして得られた場合を考える．まこともできるし，また 3 行目のようにノード単体をず，依存するファイルの末尾を置き換え，b.sml とAbsynInterface.ppg.sml

AbsynFormatter.sml

Absyn.ppg.sml

FormatTemplate.ppg.sml

Fixity.sml

ABSYN_FORMATTER.sig

AbsynSQL.ppg.sml

Symbol.ppg.sml

図3

ディレクトリ absyn 内の依存関係グラフ

c.sml というソースファイル名を得る．これらの名

4. 2. 5 依存関係グラフ作成の手順と例

前を用いてノードとエッジの定義を行う．ノードの定作成したシステムを用いて依存関係グラフを作成

義は a.sml，b.smi，c.smi の 3 つとなり，エッジのする手順を示す．まず，依存関係を表示したいファイ

定義は a.sml -> b.smi と a.sml -> c.smi の 2 本

ルをすべて，改造したコンパイラに与え，それぞれにとなればよい．生成したコードは，入力ファイル名の対応する DOT 言語コードを生成する．次に，生成さ末尾に.dot を付加したファイルに文字列として出力れた DOT 言語コードすべてを，第 4. 2. 2 節で示しする．

た単純な方法で，一つのコードにまとめる．この処理

4. 2. 4 コード生成機能のコンパイラへの実装

は単純な文字列の結合であるため，シェルスクリプ

本研究では，DOT 言語コード生成までの機能を，トで作成したスクリプトを用いて行う．そして，1 つ

コンパイラ内部に実装した．
冒頭で述べた NameEvaluation フェーズ実行時のにまとめたコードを Graphviz に与えることで，複数ファイル間の依存関係グラフを作成する．

ライブラリ関数の呼び出しをすべてトレースすると，実際に依存関係グラフを作成した例を示す．ここでBasis ライブラリのトップレベルや，プリミティブなは，SML#コンパイラの一部分である，抽象構文木に

名前の，定義や参照の情報がすべて得られる．しかし関連するファイルが集まったディレクトリ absyn 内

これらの情報は．ユーザーが入力したファイル上の定の，すべてのソースファイルを入力とし，グラフの作義や参照の情報ではないため，コードリーディングに成を行った．

はあまり有用ではないと思われる．そこで，入力した依存するファイルをすべて表示するとグラフが巨大ファイル，すなわちユーザが記述した部分の参照関になるため，表示するファイルは同一のディレクトリ

係の計算時にのみ，ライブラリ関数の呼び出しをト内のものに制限した．ファイル名は，実際にはファイレースするようにした．そして，参照関係リストから

ルのフルパスを表す文字列として扱われているので，

DOT 言語コードを生成するモジュールをコンパイラ

この制限を行う処理は容易である．

内部に新たに作成し，NameEvaluation フェーズ終了

作成されたグラフを図 3 に示す．このグラフから，後にこのモジュールの関数を呼び出すことで，DOT

各ファイル間の依存関係を視覚的に把握することがで

言語コードを生成するように改造を加えた．

きる．

検討中である．

5 今後の課題と関連研究• 種々のコードリーディング機能の実現．

以上報告した内容は，正確な名前の参照関係に基づ一つのソースファイルに限れば，SML#コンパイ

くコードリーディングツール開発の最初のステップでラの NameEvaluation フェーズは，そのファイあり，理想的なツール開発にはさらなる種々の拡張がル内のプログラムが使用する名前に関するほぼ必要である．我々は，本研究で提示したアプローチにすべての情報を収集する機能を持っている．本稿

従って，本格的なコードリーデングツールを開発中でで対象とした情報以外でも，たとえば以下の情報あり，それら詳細を本稿に続く論文にて報告予定であが容易に収集可能である．

る．以下，現在検討を進めているいくつかを紹介した
後，既存研究との関連を論じる．

• より正確な複数のファイル間の対応．
我々のアプローチは，コンパイラの機能を利用し– 関数やストラクチャ等のスコープを持つ構
文の範囲– ソースファイルの名前定義とインターフェ
イスファイルの名前定義の対応て名前の正確な参照関係を得ることを基礎としこれら情報を NameEvaluation のトレース情報ている．コンパイラの行う解析によって，一つのとして加えることによって，以下を含む種々のファイルからみた名前の構造は正確に把握できる

コードリーディング支援機能の実現が可能と考えが，インターフェイスファイルを通じて参照されられる．

る種々の資源（型や関数）を実際に定義している
別のソースファイルの関連は得られない．そのため，現状は，インターフェイスファイルに対し同名のソースファイルが存在し，そこに各資源が定– 定義された名前に対して，外部からの参照
を含む参照箇所一覧．

– 関数やストラクチャなどのスコープをもつ資源が定義する名前の一覧

義されているという簡単な仮定のもとに，複数– 同資源のネスト構造

ファイル間の依存関係を作成しており，インター– ソースファイルのサマリ情報

フェイスファイルとソースファイルの正確な対応– 使用されている名前の索引を考慮していない．この問題は，インターフェイ

本研究は，プログラムの名前の定義と参照の関係

スファイルを介して接続されている複数のソーをデータとして取り出し，そこからコードリーディン

スファイル集合からなる，システム全体のコード

グに有用な情報を生成するという２段階の戦略をとっリーディング支援の問題の一つと捉えるのが妥ている．さらに，この第一段階は，コンパイラの静的当と考え，現在，このシステム全体のコードリー

分析能力を使って正確な情報を取り出すことに成功

ディング支援の枠組みを研究中である．一般的している．これに対して，多くの既存研究では，プロな方針としては，システムを構成するインター

グラムに対して独自の分析機構を実装することによっフェイスファイルとソースファイル対応を入力とて行われている．例えば [4] では，Datalog を用いてして，各ソースファイルを解析し，結果をマージ

コードリーディングのための依存関係を含む種々の情するというアプローチが有力と考えられる．シス

報を含む Java ソースコード表現を生成している．こテムを構成するインターフェイスファイルとソーれらアプローチは，より柔軟に有用な情報をが収集でスファイル対応は，システムの構成情報等にも必きると言う利点があるが，一方正確な静的解析器の構要であり，それらを系統的に生成する機能の一部

築は困難を伴う課題である．

が，すでに SML#コンパイラに実装されている．

このアプローチを発展させる一つの方針として，得SML#コンパイラのこれら機能を系統的に拡張られた参照情報データに対する宣言的な問い合わせ

し，システム全体のファイル間の資源の定義と参言語を設計するアプローチが考えられる．Datalog を照に関する依存関係を記述し分析する枠組みを

問い合わせ言語としてコードの種々の属性を取り出す

CodeQueires [5] のアプローチや，コードに関する情

ば，有用性の高いコードリーディング支援ツールの実報の提示方法を宣言的な言語を用いてプログラムす現が可能と考える．これら機能の実現方式や実装方式

る JQuery [7] [6] のアプローチは参考になると思われが現在および今後の課題である．

る．また，一方得られたデータの表示に関しては，本研究で実装したグラフ描画言語を用いたソースファイ

謝辞

ルの単純な依存関係グラフ以外にも，プログラムの資本研究の一部は，以下の研究補助金の助成を受けて源間の種々の関連のグラフ表現が可能と思われる．グラフによる可視化の方式を検討する上で，GraphLog[3] のアプローチは参考になると思われる．

実施されたものです．

1. 科 学 技 術 補 助 金 基 盤 研 究（B) 課 題 番 号
25280019「ML 系多相 型言語 SML#の実用 化技術に関する基礎研究」

6 まとめ
本研究では，プログラム中に現れるすべての名前に関して，その名前の属するカテゴリ，名前が定義出

2. 文部科学省委託研究「イノベーション創出を支える情報基盤強化のための新技術開発— 高機能
高可用性情報ストレージ基盤技術の開発」

現であるか参照出現であるかの別，さらに，参照に対する定義の関係を正確に分析収集し，それら情報を

参 考 文 献利用しユーザにコードリーディング機能を提供する[1] Ctags, ctags.sourceforge.net.
[2] Graphviz, http://www.graphviz.org/.
[3] Consens, M. P., Mendelzon, A. O., and Ryman,
A. G.: Visualizing and Querying Software Structures, ICSE, Montgomery, T., Clarke, L. A., andGhezzi, C.(eds.), ACM Press, 1992, pp. 138–156.
[4] Eichberg, M., Kloppenburg, S., Klose, K., andMezini, M.: Defining and continuous checking ofstructural program dependencies, ICSE, Schäfer,W., Dwyer, M. B., and Gruhn, V.(eds.), ACM,
2008, pp. 391–400.
[5] Hajiyev, E., Verbaere, M., and de Moor, O.: CodeQuest: Scalable Source Code Queries with Datalog, ECOOP, Thomas, D.(ed.), Lecture Notes in
Computer Science, Vol. 4067, Springer, 2006, pp. 2–
27.
[6] Janzen, D. and Volder, K. D.: Navigating andquerying code without getting lost, AOSD, 2003,
pp. 178–187.
[7] Volder, K. D.: JQuery: A Generic Code Browser
with a Declarative Configuration Language, PADL,
Hentenryck, P. V.(ed.), Lecture Notes in Computer
Science, Vol. 3819, Springer, 2006, pp. 88–102.

枠組みを提案し，SML#言語を対象としコードリー
ディングツールを作成した．SML#言語は，名前の使
い分けによって言語レベルでモジュール構造を実現している Standard ML 言語に，分割コンパイル機能を加えて拡張された言語であり，本研究の対象として最適なものと考える．本研究では，SML#コンパイラが名前の解釈行なっている NameEvaluation フェー
ズを直接利用することによって，正確な名前の定義や参照関係の情報を系統的に取得することに成功している．ユーザにコードリーディング機能を提供に関しては，種々の可能性があるが，本研究では，その最初のステップとして，名前の参照関係によるプログラ
ムモジュール間の依存関係のグラフの描画，および，EMACS エディタ上での参照位置から定義位置へのカーソルジャンプを実現した．本稿で示したアプロー
チを，前節で論じた種々の機能を含めて拡張するなら