smith check, fmt, lint and lsp
smith fmt、smith lint、smith lspは、コンパイラと同じLLVMからsmithにリンクされたclang-format、clang-tidy、clangdであり、すべてのマシンで同じフォーマットとリントが行われます。
プロジェクトに対して:引数なし
各動詞はすべてのプロジェクトで同じ意味を持ち、build.cが宣言する内容を読み取ります。プロジェクトはこれらのタスクを記述する必要はありません。
smith fmtは、Gitが認識するすべてのC、C++、Objective-C、.smithファイル(追跡されているもの、および無視されていないが追跡されていないもの;.c .h .m .mm .cpp .cc .cxx .hpp .hh .smith .metal)を.clang-formatに従って書き換えます(.metalファイルはC++としてフォーマットされます。clang-formatが認識しない拡張子に対しては、その言語が指定されます)。smith fmt --dry-run(または-n、--Werrorまたは-iと共に)およびsmith lint --quietもプロジェクト形式です。オプションのみでファイル名は指定しないため、標準入力の待機は発生しません。その他のオプション、またはファイル名が指定された場合は、ツールとして動作します(smith fmt --assume-filename=x.cは標準入力を読み取ります)。.clang-format-ignoreに記載されたファイル(clang-format自身が読み取るファイル:生成されたparser.c、フィクスチャなど)は処理されません。Gitリポジトリの外部では、ファイルを指定するよう求められます(smith fmt -i <files>)。smith lintは、コンパイルが読み取るもの(生成されたヘッダー)をビルドし、ビルドのコンパイル対象(smith_object、およびビルドがコンパイルしないソース用のsmith_compile_command)のうち、プロジェクト自身のソースに対して.clang-tidyを使用してclang-tidyを実行します。.smith/、build/の出力やパッケージは対象外です。すべての.smithソースは、smith lint x.smith -- <flags>と同様にリントされます。ビルド自身のものはそのコンパイルコマンドで、その他のGitが認識する.smithファイルは最も近いコンパイルコマンドで実行されます。ただし、.clang-format-ignoreで指定されたファイルは除外されます(これは通常のソースではないファイルの単一リストです:テスト入力、意図的に間違ったフィクスチャ、生成・コピーされたファイル;smith fmtもこれを読み取るため、2番目のリストはありません)。検出結果があるとリントは失敗します。最終行にlinted N filesと表示されます(smith checkではlint ok: N files)。.smithソースを持つプロジェクトで1つもリントされなかった場合は失敗します。フォルダ内の.clang-tidy(例:InheritParentConfig: trueと他のチェック)はそのフォルダに適用されます。smith lintはインクリメンタルです。clang-tidyの結果は~/.cache/smith/lintにキャッシュされ、ファイル、そのインクルード(.smithファイルの場合はインポートするモジュールの生成ヘッダーも)、.clang-tidy、およびsmithが変更されていない限り再利用されます。そのため、最終行はsmith lint: linted 180 files (3 run, 177 cached, 1.2 s)のようになり、変更がないツリーではclang-tidyは実行されません。SMITH_LINT_CACHE=0でキャッシュを無効化、SMITH_LINT_CACHE=whyで実行理由を表示、smith cache clean lintでキャッシュをクリアします。clang-tidyが失敗したファイルは最終行に表示されます(smith lint: c.c: exited with status 1、またはwas killed by signal 9。後者は自身の出力は表示されません)。smith lint --changed[=<ref>]は、<ref>とのマージベースから変更されたファイルのみをリントします(デフォルトはブランチの上流、なければorigin/HEADのブランチかorigin/main。ローカルのmainは使用されません。いずれも存在しない場合は--changed=<ref>の指定が必要でエラーになります。表示される行でベースが示されます。編集および追跡されていないファイルもカウントされます)。また、それらのファイルがインクルードまたはインポートするファイルもリントします。変更された.clang-tidy、ビルドファイル、shim/、patches/はすべてのファイルを選択します。影響を受けるファイルがない場合はその旨が表示され成功します。プレーンなsmith lintはすべてをリントします(CI用)。ネットワークから取得できないパッケージを待つファイル(クラウドサンドボックス内のツリーサイターパーサーなど)は名前でスキップされます(smith lint: skipped runtime/tree_sitter_data.c: the tree-sitter parser it embeds cannot be fetched (<url>))。残りはリントされます。CI(CIまたはSMITH_PRIORITY=ci)の場合は代わりに失敗します。まだビルドされていないプロジェクト(compile_commands.jsonがない)でsmith lint FILEを実行すると、smith build smith_needsを一度実行するよう促して停止します。生成ヘッダーがないことをエラーとして報告するのを防ぎます。smith docsはknowledge/とスキル(smith-docs)をチェックします。smith checkは、fmt(clang-formatのdry run)、docs、lint、test、proveをこの順序で実行し、失敗しても停止しません。各部分は1行を出力します:smith check: <part> ok: <detail> (<n> s wall, <n> s cpu)またはFAILED (status N)、失敗の抜粋と完全なログのパス(.smith/log/<part>.log)が続きます。合格した部分の出力もそこに含まれます。smith check -vはすべてをリアルタイムで表示します。次にsmith check: promises: N(smithが信頼するもの。必要に応じてデフォルトビルドから作成されます)が表示され、最終行はsmith check: okまたはsmith check: failed: <parts>です。いずれかが失敗すると終了ステータスは1になります。prove行はカバレッジを示します:smith check: prove ok (4 of 23 functions): ...(プロジェクトの、独自の契約を持つ関数。証明するものがない場合は0 of N functionsで成功。低カバレッジで失敗することはありません)。各部分の行はwall時間とCPU時間で終わります((91.2 s wall, 480.1 s cpu):CPUはユーザー+システム、その部分と待機したプロセスの合計)。-Dオプションと-v以外の引数は取りません。macOS以外のホストでは--skip-macosを付けてテストを実行し、その旨を表示します(the macOS-only tests do not run on this host)。smith testはビルドのタスクのテーブルで終了します(.smith/task/<name>のステップ。smith自身のtest-<name>として)。最も遅いものから順に、wall、CPU、システム秒数、各タスクが開始したsmithプロセス数(SMITH_START_LOG。smithがmainの開始時に追記します。環境をクリアするタスクはカウントされません)が表示されます。最も遅い8つ、smith check -vまたはSMITH_ACCOUNT=allの場合はすべてのタスク、SMITH_ACCOUNT=noの場合は何も表示されません。タスクはsmith --smith-account <file> <name> <command...>を通じて実行され、これが行を書き込みます。- 新しい構文の
.smithファイルはclang-formatの対象外です (#1890, #1886, #2040):smith fmtは、.smithファイルが現在の構文(行が現在の構文またはCのみが持つ形式で始まる、現在のパーサーがエラーなく読み取れる、または新しい構文での最初のエラーに//コメントのような修正がある)であるか、解析エラーがあり新しい構文のみが持つ行(fn、let、pub、#)がない場合を除き、smith自身のフォーマッター(front::format)に送信します。新しい構文のファイルには単一のスタイルが適用され、.clang-formatは不要です(一貫したインデントは4スペース、1行に1文、#コメントは保持)。解析エラーのある新しい構文のファイルはpath:line:column: messageとして報告され、バイト単位でそのまま残され(--dry-runでも同様)、smith fmtは終了コード1で終了します。clang-formatに送信されることはなく、破損を防ぎます。これは冪等であり、.clang-format-ignoreを尊重し、--dry-run/-nは変更されるファイルを名前で表示します(path: would be formatted)が書き込みは行いません。現在の構文の.smithファイル(およびすべての.c)は、移行(#1631)でそのフォールバックが削除されるまでclang-formatのままです。tests/fmt_smith_test.smithでテストされています。 smith fmt FILEは、拡張子がこれらのいずれでもないファイル(.sh、.mdなど)を拒否します。エラーでファイル名を表示し、書き込みは行いません。clang-formatがCとして読み取り破損する可能性があるためです。--assume-filename=x.cでファイルの種類を指定できます。- コミット前:
smith fmt、次にsmith checkを実行します。 - 独自のタスク(カスタムチェック、ジェネレーター)はbuild.cで
smith_taskとして定義し、smith build <task>で実行します。fmt、lint、docs、prove、check、run、testという名前のタスクやエイリアスは許可されません。smith build checkおよびその他の動詞名は拒否されます。動詞を使用してください。
ファイルに対して:引数あり
smith lint DIR(引数にフォルダが含まれる場合)は、その配下にあるGitが認識し、.clang-format-ignoreで指定されていないC、C++、Objective-C、.smithソースをリントします(プロジェクトリントと同様。ヘッダーはソースを通じて読み取られるため含まれません)。smith lint front -- <flags>やsmith lint front/ main.cはファイルと混在できます。該当するソースがないフォルダはエラーになります。
clang-tidyのアナライザー(clang-analyzer-*)は、<smith/contract.h>のsmith_requires、smith_ensures、smith_invariant、smith_assertを仮定(target::static_analyzer)として読み取ります。そのため、契約で境界が指定されたインデックスはclang-analyzer-security.ArrayBoundによって報告されません。
smithのデフォルト.clang-tidyは、ノイズとなる2つのアナライザーチェック(game、learner、smithで616件中546件)をオフにします:clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling(すべてのmemcpy)とclang-analyzer-optin.performance.Padding。プロジェクト独自の.clang-tidyでオンに戻すには(smith lint --dump-config > .clang-tidyで有効なファイルを書き出します)、該当する-clang-analyzer-...行を削除します。
smith lint --fix FILE.smith...(--なし)は、smith自身のフロントエンドが解析エラーで保持する修正を適用します(古い形式またはCスタイルの形式をsmithのスペルに変換:1つの修正の編集はすべて一緒に適用されるか、まったく適用されません。重複する修正はスキップされ、ファイルは何も適用されなくなるまで、最大16パスで再解析されます)。path: N fixes appliedと表示されます。2回目の実行では0 fixes appliedと表示されます。.smithファイルのみを読み取り、フルスミスが必要です。-- <flags>を付けると、上記のclang-tidyの--fixになります。まだどの解析エラーも修正を保持していません。古い形式はチケットごとに修正が行われます(#1428)。
smith lint FILE は、build/<os>/front-project/.smith/includeフォルダが存在する場合、--extra-arg=-Iを追加します(フロントモジュールはこれを介して相互にインポートします)。macOS以外のホストでは1行表示します。CIはMacでリントし、u64はunsigned long long、usizeはunsigned longであるため、(U64)(i + 1)とusizeの組み合わせはそこでのみbugprone-misplaced-widening-castの検出になります。そのようなキャストは(U64)i + 1と記述して修正します。
引数がある場合、これらはツールとして機能します:smith fmt main.cはファイルをその場で書き換えます(clang-formatは出力するだけですが、smithはファイル名を指定し、他のモードを選択するオプションがない場合に-iを追加します:-n、--dry-run、--lines、--assume-filenameはclang-formatの意味を保持し、smith fmt --assume-filename=x.c < x.cは結果を出力します)。smith fmt --dry-run --Werror main.c、smith lint --quiet main.c -- <flags>、smith lsp --check=main.cなど。プロジェクトの.clang-formatと.clang-tidyが適用されます。stage0のsmithはHomebrewのツール、または$SMITH_CLANG_FORMAT、$SMITH_CLANG_TIDY、$SMITH_CLANGDを実行します。
smithのデフォルト設定:プロジェクトにファイルがない場合(issue #43)。.clang-format(または_clang-format)も.clang-tidyもないプロジェクトは、clang-formatとclang-tidyが行うように各ファイルのフォルダから上に向かって検索され、smith自身に組み込まれたデフォルト(今日smith newが書き込むファイル)でフォーマットおよびリントされます。何も書き込む必要はありません。プロジェクト内のファイルはsmith全体を置き換え、決してマージされません。明示的な--style(または--fallback-style)、--config、--config-fileが指定された場合はそれが優先されます。標準入力の場合、--assume-filenameが検索場所を指定します。プロジェクトファイルがあるファイルとないファイルを1つのコマンドで名前指定して実行できます(smithは後者を別のプロセスとして実行します)。smith fmt --dump-config > .clang-formatおよびsmith lint --dump-config > .clang-tidyは有効な設定(プロジェクトのもの、なければsmithのもの)を出力するため、プロジェクトはそれをダンプしてデフォルトを取得し、必要な部分だけを編集できます。デフォルトは意図的にまれにしか変更されないため、固定したいプロジェクトはダンプします。smithはそのコピーを$XDG_DATA_HOME/smith/defaults/(なければ~/.local/share/...)に書き込みます。smith ccは影響を受けません。純粋なパススルーのままです。
.smith ファイル
smith fmt x.smith(および-i、--dry-run、--assume-filename=x.smithを伴う標準入力)は、.smithファイルをCとしてフォーマットします。::パス、module a::b;、import a::b as x;行、import <sys/wait.h>;はそのまま保持されます。引数なしのsmith fmtはプロジェクトの.smithファイルもフォーマットします(Gitが認識するもの)。関数内のimportとmoduleはCと同様に名前として扱われます。clang-formatに.smithパッチが適用されたsmithが必要です(stage0はHomebrewのものを実行し、.smithをC++として読み取るため、throwのようなC++キーワードであるCの名前を誤って解釈します)。clangdも.smithファイルを同じ方法でフォーマットします。
smith lint x.smith -- <flags>(clang-tidy、プロジェクトの.clang-tidyを使用)は、.smithファイルをsmith ccが読み取るのと同じ方法でリントします(-x c、標準を指定しない限り-std=gnu2y。コンパイルデータベースの独自のコマンドはそのまま使用されます)。ソースが記述されたとおりに報告します:検出、メモ、修正提案は.smithテキストの行と列に従い、名前は記述されたとおりに表示されます(モジュール内のareaとBox、インポートされたbox::area、決してgeometry_box_areaではありません)。readability-identifier-namingはモジュールのファイルスコープ名の記述された名前を判断するため、テンプレートのルール(スネークケースの関数と変数、パスカルケースの型)がareaとBoxに適用され、--fixはソース内のトークンを書き換えます。サイズ型(U32、I32)、低レベルのプロトタイプのコピー、smith buildが書き込むヘッダーは決して報告されません。エクスポートに関する検出は、各インポーターではなくモジュールのファイルで報告され、そこで修正されてもインポーターの名前は変更されません。他のチェックはメッセージに記述された名前を表示しますが、名前自体を比較するチェック(長さや予約名のチェックなど)は依然として低レベルの名前を読み取ります。トークンフックを持つclangを備えたsmithが必要です(smith cc --smith-which x.smithでtoken-hook yesと表示されます)。stage0はHomebrewのclang-tidyを実行しますが、これは.smithを読み取れません。
このファミリーの他のスキル:smith-check-lints。