Skip to content

自己完結していないライブラリファイルを自動検出して警告する #94

Description

@TwoSquirrels

#20 で文書化した「各ファイルの自己完結性」の違反は、現状ユーザーが自分で気をつけるしかない。特に namespace で他ファイルの #include をラップする構成は、修飾なしで使うと黙って意味が変わったままコンパイルが通り得る (Silent Failure)。自動で検出して警告できれば、文書を読んでいないユーザーも守れる。

検出方式は 2 案あり、どちらにするか (または併用するか) は要検討。

案 A: 登録時 (library add/update) に tree-sitter で検出する

preproc_include ノードの祖先に C++ のスコープ (namespace_definitiondeclaration_listcompound_statement・クラス本体) がいたら警告する。

  • 実験で実現可能なことを確認済み。#ifdef _MSC_VER#include <intrin.h> のようなプリプロセッサ条件の内側は正当 (AC Library が実際にやっている) なので、preproc_if/preproc_ifdef 系の祖先は許す区別が必要で、実験ではこの区別で正しく分離できた。
  • 利点: 問題のあるライブラリを登録した時点で気づける。バンドルを待たない。
  • 限界: 検出できるのは「ラッパー側」(スコープ内に #include を書いたファイル) だけ。相方の断片ファイル単体や、#include を使わない関数分割 (int f() { / } の 2 ファイル) は検出できない。

なお tree-sitter の has_error() で構文の非完結を直接検出する案は不適と判明している。波括弧なしの文レベルマクロ (rep(i, n) s += i;) や属性マクロ付きの関数定義 (ATTR_HOT int f()) という競プロライブラリの日常的な書き方が ERROR になり、偽陽性が多すぎる。「正当な操作で必ず消える警告だけを出す」方針 (architecture.md) に反する。

案 B: バンドル時にプリプロセス結果のファイル境界で検出する

プリプロセス出力を字句解析して波括弧の深さを追跡し、linemarker によるファイルの切り替わりが深さ 0 以外の位置に来ていたら警告する。

  • 利点: ラッパー側・断片側・関数分割まで、自己完結性違反の全パターンを原理的に検出できる。実際に採用された #ifdef 分岐だけを見るので、プリプロセッサ起因の偽陽性もない。
  • 考慮点: 文字列・コメント・raw string を正しくスキップする字句解析が要る (detect.rs の logos レキサーを深さ追跡に拡張する形が考えられる)。検出がバンドル時まで遅れる。維持指定ライブラリは展開されないため対象外になる (もっとも維持指定なら tree-shaking もされないので実害はない)。

補足

  • どちらの案でも、エラーではなく警告に留める (「開いた語彙は警告」の方針。ライブラリはユーザーの資産であり、risundle の判定が誤る余地を残すため)。
  • 警告文からは docs/compatibility.ja.md (risundle が対応できるライブラリの条件を新規文書化する #93 で追加) へ誘導すると、警告の意味と直し方が伝わる。

関連: #20 (条件の文書化)、#93 (文書の PR)

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Kind/EnhancementImprove existing functionalityModule: BundleThe tree-shaking pipelineModule: LibraryThe library registration domainPriority/HighThe priority is highSilent FailureBug that exits 0 while producing incorrect output

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions