オルタナティブ・ブログ > 森崎修司の「どうやってはかるの?」 >

計測できそうでできない多くのこと。エンピリカル(実証的)アプローチで。

オープンソースのプルリクエストを8種類の読みやすさ改善に分類した研究

»

Understanding code understandability improvements in code reviewsというオープンソースソフトウェアのプルリクエストのうち、コードの読みやすさを向上するプルリクエストを分類してどのような読みにくさ(コードスメル: コードの不吉な匂い)を解消したものかを調べた論文を紹介します。原典は学会のサイト(定期購読か購入が必要です)か著者の投稿版(無料、最終版とは限りません)にあります。

Oliveira, D., Santos, R., De Oliveira, B., Monperrus, M., Castor, F., & Madeiral, F. (2024). Understanding code understandability improvements in code reviews. IEEE Transactions on Software Engineering, 51(1), 14-37.

対象ソースコードと選定基準
この研究ではGitHub上でホストされているJavaのオープンソースプロジェクトを調査対象としています。以下の基準で363のリポジトリを選んで対象としています。

  • Javaプロジェクトであり、10以上のスター、10人以上のコントリビューターが存在し、フォークされたリポジトリではない。

  • 活発なコードレビューがある(2020年に月に1回以上のプルリクエストがあり、インラインのコードレビューコメントが含まれていること)。

  • プルリクエストのマージがGitHub上で追跡可能である。

  • プロジェクトが主にソースコードで構成されており、レビューコメントが主に英語で書かれている。

調査方法
363リポジトリから抽出した35万件近いインライン・コードレビューコメントの中から、統計的に有意な2,401件のコメントを無作為抽出して分析しています。具体的な手順は以下の通りです。

  • 分類と頻度調査
    2,401件のコメントを分析し、コードの理解しやすさの向上に関連しているかを分類した。

  • コードスメルの特定
    理解しやすさに関連するコメントの中からランダムに385件を抽出し、コードスメルの種類と、それがコードのどの部分(メソッド、クラスなど)に含まれているのかを特定、分類した。

  • プルリクエストがマージされいている割合と修正内容の分析
    理解しやすさを向上するプルリクエストがコードに反映されたか(マージ率)を、それ以外のプルリクエストと比較分析した。また、受け入れられた323件のプルリクエストに対して、開発者がどのようにコード変更したか分析した。

  • 差し戻しの調査
    反映されたプルリクエストが、その後のコミットで反映前に戻されていないか(リバートされていないか)を履歴から追跡した。

  • Linterのカバー率調査
    4つの一般的な静的解析ツール(Spotbugs、PMD、SonarQube、Checkstyle)を用いて、特定されたコードスメルを既存のツールで自動検出できるかを調査した。

結果
レビュアーが指摘したコードスメルは以下の8つのカテゴリーに分類できました。

  • 不十分または不適切なコードの説明 (22.3%, 86件)
    Javadocやインラインコメント、Javaのアノテーションに関するコードスメル。ドキュメントの欠落、誤った記載、不適切な配置が含まれる。また、不要なコメントや、非推奨メソッド(@Deprecatedなど)に対するステータスに関するドキュメントの欠落・誤りなどもこのカテゴリに含まれる。

  • 不適切な識別子 (20.3%, 78件)
    変数、メソッド、パラメータなどの識別子の内容やスタイルに関するコードスメル。識別子のタイポ、命名規則違反(例:小文字にすべきパラメータ名が大文字になっている)、機能や型を正しく表現していない名前などが含まれる。

  • 複雑、冗長、または不適切なロジック (18.2%, 70件)
    式やコードの構造が複雑で長すぎることに関するコードスメル。冗長なメソッド呼び出し、長すぎるメソッドの実装、記述が冗長な無名内部クラス、重複コードを含んだ複雑なif-else文、外部APIクラスの不適切な使用などが該当。

  • 不要なコード (13.2%, 51件)
    コードの機能に影響を与えることなく安全に削除できるソースコードの断片に関するコードスメル。単純な不要コードやテキストの重複にとどまらず、未使用のインポート、クラス、メソッド、変数、定数、コメントアウトされたままのコードなどが含まれます。また、不要なthisの使用や不必要に作成された中間変数など、冗長なコードもこれに分類される。

  • 不一致または崩れたフォーマット (10.9%, 42件)
    スペース、中括弧、括弧の配置や、フォーマットスタイルに関連するコードスメル。縦や横のスペースの不足または過剰、式の評価順序を明確にするための括弧の欠落、中括弧や改行の不足、プロジェクトのフォーマットガイドラインに違反するスタイル(例: if文の改行ルール違反)なども含まれる。

  • 誤り、漏れ、または不適切な文字列表現やリテラル (8.1%, 31件)
    例外やログの引数として使われる自然言語の文字列メッセージや、文字列リテラルのスタイル・正確性に関するコードスメル。文字列内の不適切な単語の選択、メッセージの欠落、コード規約に合致していない文字列表現、および文字列値のタイポなどが含まれる。

  • 不適切なロギングと監視 (4.7%, 18件)
    ログ出力や例外処理のステートメントに関するコードスメル。デバッグや監視を容易にするためのログの欠落、不要なログの出力、一貫性のないログレベル(テスト環境で毎秒出力されるなど)、詳細を伝えない汎用的な型での例外スローなどが含まれる。

  • 定数使用の漏れ (2.3%, 9件)
    リテラル値を直接使用している(マジックナンバーや直書きの文字列など)箇所で、定数で置き換えられる部分を指すコードスメル。すでに宣言されて利用可能な定数が存在しているにもかかわらず、その定数を再利用していないケースも含まれる。

調査手順にあるその他の調査内容の結果として以下が報告されています。

  • レビューにおける高い重要性
    分析した全コメントのうち42.2%(2,401件中1,012件)がコードの理解しやすさに関連するものであった。

  • 高いアクセプト率と低いリバート率
    理解しやすさに関するプルリクエストは、他に比べて受け入れられる確率が有意に高く、83.9%の提案が受け入れられてコードベースに統合された。さらに、適用された修正パッチのうち、最終的にリバートされたのは1%未満(2件)だった。

  • 既存ツール(Linter)の限界
    4つのLinterツールで検出できたコードスメルは特定されたコードスメルの30%未満(323件中89件)だった。指摘された課題の多くが「自然言語(ドキュメントや識別子の意味)」に関連しているか、「プロジェクト固有の文脈やスタイル」に依存しているため。

Comment(0)