ソフトウェア開発プロジェクトにおいて、ソースコードの構造を視覚的に理解することは非常に重要です。特に、大規模なプロジェクトや複雑なアーキテクチャを持つアプリケーションでは、コードの流れや関数間の依存関係を把握することがプロジェクトの成功に直結します。今回は、Understand APIを活用してC/C++のソースコードからシーケンス図を自動生成する方法をご紹介します。さらに、PlantUMLを使用してこれを視覚化し、コードの理解を深める手助けをします。
必要なツール
- Understand: 静的解析ツールで、豊富なAPIを提供しており、ソースコードからさまざまなデータを抽出できます。
- Python: UnderstandのPython APIを使用します。
- PlantUML: シーケンス図などのUML図を生成するツールです。
ステップバイステップの説明
- Understandプロジェクトの準備: まず、Understandでプロジェクトを開き、分析したいソースコードをプロジェクトに追加します。
- スクリプトの作成: Pythonスクリプトを書いて、特定の関数から始まる関数呼び出しの階層を解析します。このスクリプトは再帰を使用して、深さ優先検索で関数呼び出しを追跡します。
- 再帰の制御: 再帰関数の呼び出しを5回に制限し、シーケンス図が過度に複雑になるのを防ぎます。
- シーケンス図の生成: PlantUML記法を用いて、解析結果をシーケンス図として出力します。これにより、ファイル間の関数呼び出しの関係が視覚的に明確になります。
コードサンプル
以下は、UnderstandとPlantUMLを使ってシーケンス図を生成するためのPythonスクリプトの例です。
import understand as und
# Understandプロジェクトを開く
db = und.open("path/to/project.und")
def generate_sequence_diagram(func, depth=0, output=None, recursion_count={}):
if output is None:
output = ["@startuml"]
# 関数が宣言されているファイル名を取得
func_file = func.parent().longname()
# 再帰の深さをチェックし、上限を超えていたら戻る
if recursion_count.get(func.longname(), 0) >= 5:
return
# 再帰カウントを更新
recursion_count[func.longname()] = recursion_count.get(func.longname(), 0) + 1
# Activate the function
output.append(f"{depth * ' '}activate {func_file}")
# Handle function calls
for ref in func.refs("call", "Function"):
callee = ref.ent()
callee_file = callee.parent().longname()
output.append(f"{(depth + 1) * ' '}{func_file} -> {callee_file}: {callee.name()}")
generate_sequence_diagram(callee, depth + 1, output, recursion_count)
# 再帰カウントを減少
recursion_count[func.longname()] = recursion_count.get(func.longname(), 0) - 1
# Deactivate the function
output.append(f"{depth
* ' '}deactivate {func_file}")
if depth == 0: # Only append this line at the end of the initial call
output.append("@enduml")
return "\n".join(output)
# シーケンス図の生成
diagram = generate_sequence_diagram(db.lookup("main", "Function"))
print(diagram)
このスクリプトは、プログラムの各関数がどのファイルに定義されているかを基に、関数間の呼び出しを追跡し、それをシーケンス図で表現します。再帰制御により、図が適切な複雑さに保たれ、コードの理解が容易になります。これは、特に大規模なソフトウェアプロジェクトやリファクタリングの際に非常に有効なツールです。