smith check, fmt, lint und lsp
smith fmt, smith lint und smith lsp sind clang-format, clang-tidy und clangd, die aus demselben LLVM wie der Compiler in smith eingebunden sind, sodass auf jedem Rechner gleich formatiert und gelintet wird.
Im Projekt: ohne Argumente
Die Verben bedeuten in jedem Projekt dasselbe und lesen, was build.c deklariert; ein Projekt schreibt keine Aufgabe dafür.
smith fmtüberschreibt jede C-, C++-, Objective-C- und.smith-Datei, die git sieht (getrackt und ungetrackt, aber nicht ignoriert;.c .h .m .mm .cpp .cc .cxx .hpp .hh .smith .metal) gemäß.clang-format(eine.metal-Datei wird als C++ formatiert, die Sprache, die clang-format einer Erweiterung gibt, die es nicht kennt).smith fmt --dry-run(oder-n, mit--Werroroder-i) undsmith lint --quietsind ebenfalls die Projektformen: ausschließlich Optionen, keine Dateinamen, sodass sie nie auf die Standardeingabe warten; jede andere Option oder ein Dateiname macht sie zu den Werkzeugen (smith fmt --assume-filename=x.cliest die Standardeingabe). Eine in.clang-format-ignoregenannte Datei (clang-format liest sie selbst: ein generiertesparser.c, eine Testvorlage) bleibt unberührt. Außerhalb eines Git-Repositories wird gesagt, die Dateien zu benennen (smith fmt -i <dateien>).smith lintbaut, was die Compilate lesen (generierte Header), und führt dann clang-tidy mit.clang-tidyauf den eigenen Quellen des Projekts unter den Compilaten des Builds aus (smith_objectundsmith_compile_commandfür Quellen, die der Build nie compiliert), nebeneinander. Nicht.smith/,build/-Ausgaben oder Pakete. Jede.smith-Quelle wird gelintet wiesmith lint x.smith -- <flags>: die eigenen mit ihrem Compile-Befehl und jede andere von git gesehene.smith-Datei mit dem Befehl des nächstgelegenen Compilats, außer was.clang-format-ignorenennt (die eine Liste von Dateien, die keine gewöhnlichen Quellen sind: Testeingaben, absichtlich falsche Vorlagen, generierte und kopierte Dateien;smith fmtliest sie auch, es gibt also keine zweite Liste). Ein Befund lässt den Lint fehlschlagen; seine letzte Zeile lautetlinted N files(smith check:lint ok: N files), und ein Projekt mit.smith-Quellen, das keine lintet, schlägt fehl. Ein.clang-tidyin einem Ordner (z. B.InheritParentConfig: truemit anderen Checks) gilt dort.smith lintist inkrementell: clang-tidys Ergebnis für eine Datei wird unter~/.cache/smith/lintzwischengespeichert und wiedergegeben, solange die Datei, das, was sie inkludiert (für eine.smith-Datei auch die generierten Header der Module, die sie importiert), ihr.clang-tidyund smith unverändert sind, sodass die letzte Zeilesmith lint: linted 180 files (3 run, 177 cached, 1.2 s)lautet und ein unveränderter Baum clang-tidy auf keiner Datei ausführt.SMITH_LINT_CACHE=0schaltet es aus,SMITH_LINT_CACHE=whysagt, warum eine Datei lief,smith cache clean lintleert es. Eine Datei, deren clang-tidy fehlschlägt, wird in den letzten Zeilen genannt (smith lint: c.c: exited with status 1oderwas killed by signal 9, was nichts Eigenes ausgibt) und am Ende ihrer eigenen Ausgabe.smith lint --changed[=<ref>]lintet nur die Dateien, die seit dem Merge-Base mit<ref>geändert wurden (Standard: der Upstream des Branches, sonst der Branch vonorigin/HEADoderorigin/main, niemals ein lokalesmain; keiner davon ist ein Fehler, der--changed=<ref>benennt; die ausgegebene Zeile nennt die Basis; Bearbeitungen und ungetrackte Dateien zählen) sowie die Dateien, die sie inkludieren oder importieren; ein geändertes.clang-tidy, eine Build-Datei,shim/oderpatches/wählt jede Datei aus, und nichts Betroffenes sagt dies und wird erfolgreich. Normalessmith lintlintet alles (CI). Eine Datei, die auf ein Paket wartet, das das Netzwerk nicht bereitstellt (der Tree-Sitter-Parser in einer Cloud-Sandbox), wird namentlich übersprungen (smith lint: skipped runtime/tree_sitter_data.c: the tree-sitter parser it embeds cannot be fetched (<url>)) und der Rest wird gelintet; CI (CIoderSMITH_PRIORITY=ci) schlägt stattdessen fehl.smith lint DATEIin einem noch nicht gebauten Projekt (keincompile_commands.json) stoppt und sagt, einmalsmith build smith_needsauszuführen, anstatt die fehlenden generierten Header als Fehler zu melden.smith docsprüftknowledge/und die Skills (smith-docs).smith checkführt fmt (clang-formats Trockenlauf), docs, lint, test und prove in dieser Reihenfolge aus und stoppt nicht bei einem Fehlschlag: jeder Teil gibt eine Zeile aus,smith check: <teil> ok: <detail> (<n> s wall, <n> s cpu)oderFAILED (status N)mit einem begrenzten Auszug des Fehlschlags und dem Pfad des vollständigen Logs (.smith/log/<teil>.log; die Ausgabe eines erfolgreichen Teils ist ebenfalls dort;smith check -vgibt alles aus, während es passiert), dannsmith check: promises: N(was smith vertraut, aus einem Standard-Build, den es bei Bedarf erstellt), und die letzte Zeile istsmith check: okodersmith check: failed: <teile>; der Exit-Status ist 1, wenn einer fehlschlug. Die Prove-Zeile sagt die Abdeckung,smith check: prove ok (4 of 23 functions): ...(Funktionen mit eigenem Vertrag, vom Projekt;0 of N functions, wenn es nichts zu beweisen gibt, was ein Erfolg ist; nichts schlägt bei geringer Abdeckung fehl). Jede Teilzeile endet mit ihrer Wall- und CPU-Zeit ((91.2 s wall, 480.1 s cpu): CPU ist User plus System, des Teils und der Prozesse, auf die er wartete). Es akzeptiert keine Argumente außer-D-Optionen und-v. Auf einem Host, der nicht macOS ist, führt es die Tests mit--skip-macosaus und sagt dies (the macOS-only tests do not run on this host).smith testendet mit einer Tabelle der Build-Aufgaben (.smith/task/<name>-Schritte, wie smiths eigenetest-<name>), die Langsamsten zuerst: Wall-, CPU- und Systemsekunden sowie die Anzahl der von jedem gestarteten smith-Prozesse (SMITH_START_LOG, das smith beim Start vonmainanhängt; eine Aufgabe, die die Umgebung löscht, wird nicht gezählt); die langsamsten acht, jede Aufgabe mitsmith check -voderSMITH_ACCOUNT=all, keine mitSMITH_ACCOUNT=no. Die Aufgaben laufen übersmith --smith-account <datei> <name> <befehl...>, das die Zeile schreibt..smith-Dateien im neuen Syntax sind nicht clang-formats (#1890, #1886, #2040):smith fmtsendet eine.smith-Datei an smiths eigenen Formatierer (front::format), es sei denn, sie ist im heutigen Syntax (eine Zeile beginnt mit einer Form, die nur der heutige Syntax oder C hat, der heutige Parser liest sie ohne Fehler, oder ihr erster Fehler im neuen Syntax hat eine Korrektur, wie ein//-Kommentar) oder hat einen Parse-Fehler und keine Zeile, die nur der neue Syntax hat (fn,let,pub,#): ein Stil und kein.clang-formatdafür (jede konsistente Einrückung erfolgt mit 4 Leerzeichen, eine Anweisung pro Zeile,#-Kommentare bleiben erhalten). Eine neue Syntax-Datei mit einem Parse-Fehler wird alspfad:zeile:spalte: nachrichtgemeldet, Byte für Byte unverändert gelassen (auch mit--dry-run) und lässtsmith fmtmit Exit-Code 1 beenden: Sie wird niemals an clang-format gesendet, was sie verstümmeln würde. Es ist idempotent, beachtet.clang-format-ignore, und--dry-run/-nnennt die Dateien, die sich ändern würden (pfad: would be formatted), ohne zu schreiben. Eine.smith-Datei im heutigen Syntax (und jede.c) bleibt bis zum Wechsel (#1631), der diesen Fallback entfernt, bei clang-format. Getestet durchtests/fmt_smith_test.smith.smith fmt DATEIlehnt eine Datei ab, deren Erweiterung nicht eine dieser ist (eine.sh, eine.md), mit einem Fehler, der die Datei nennt und nichts schreibt, da clang-format sie als C lesen und beschädigen würde;--assume-filename=x.csagt, was sie ist.- Vor dem Commit:
smith fmt, dannsmith check. - Eine eigene Aufgabe (eine benutzerdefinierte Prüfung, ein Generator) ist
smith_taskin build.c und läuft mitsmith build <aufgabe>; keine Aufgabe oder Alias darffmt,lint,docs,prove,check,runodertestheißen.smith build checkund die anderen Verbnamen werden abgelehnt: Verwende das Verb.
Für Dateien: mit Argumenten
smith lint VERZ (ein Ordner unter den Argumenten) lintet die C-, C++-, Objective-C- und .smith-Quellen darunter, die git sieht und .clang-format-ignore nicht nennt, wie das Projekt-Lint (keine Header, die durch ihre Quellen gelesen werden); smith lint front -- <flags> und smith lint front/ main.c mischen sich mit Dateien. Ein Ordner ohne solche Quelle ist ein Fehler.
clang-tidys Analyzer (clang-analyzer-*) liest smith_requires, smith_ensures, smith_invariant und smith_assert von <smith/contract.h> als Annahmen (target::static_analyzer), sodass ein Index, der durch einen Vertrag begrenzt ist, nicht von clang-analyzer-security.ArrayBound gemeldet wird.
smiths standardmäßiges .clang-tidy schaltet zwei Analyzer-Prüfungen aus, die Rauschen waren (bei game, learner und smith: 546 von 616 Befunden): clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling (jedes memcpy) und clang-analyzer-optin.performance.Padding. Schalte eine im eigenen .clang-tidy des Projekts wieder ein (smith lint --dump-config > .clang-tidy schreibt die effektive Datei), indem du ihre -clang-analyzer-...-Zeile löschst.
smith lint --fix DATEI.smith... (kein --) wendet die Korrekturen an, die smiths eigener Front-End in seinen Parse-Fehlern trägt (eine alte oder C-artige Form mit ihrer smith-Schreibweise: die Bearbeitungen einer Korrektur werden zusammen oder gar nicht angewendet, eine überlappende Korrektur wird übersprungen, und eine Datei wird erneut geparst, bis nichts mehr zutrifft, maximal 16 Durchgänge) und gibt pfad: N fixes applied aus; ein zweiter Lauf gibt 0 fixes applied aus. Es liest nur .smith-Dateien und benötigt den vollständigen smith. Mit -- <flags> ist es clang-tidys --fix, wie oben. Noch trägt kein Parse-Fehler eine Korrektur: Die alten Formen erhalten ihre ticketweise (#1428).
smith lint DATEI fügt --extra-arg=-I für build/<os>/front-project/.smith/include hinzu, wenn dieser Ordner existiert (Front-Module importieren sich gegenseitig durch ihn), und gibt auf einem Host, der nicht macOS ist, eine Zeile aus: CI lintet auf einem Mac, wo u64 unsigned long long und usize unsigned long ist, sodass (U64)(i + 1) mit einem usize ein bugprone-misplaced-widening-cast-Befund nur dort ist; behebe einen solchen Cast, indem du (U64)i + 1 schreibst.
Mit Argumenten sind sie die Werkzeuge: smith fmt main.c überschreibt die Datei an Ort und Stelle (clang-format würde sie ausgeben; smith fügt -i hinzu, wenn du Dateien benennst und keine Option einen anderen Modus wählt: -n, --dry-run, --lines, --assume-filename behalten clang-formats Bedeutung, und smith fmt --assume-filename=x.c < x.c gibt das Ergebnis aus), smith fmt --dry-run --Werror main.c, smith lint --quiet main.c -- <flags>, smith lsp --check=main.c. Das .clang-format und .clang-tidy des Projekts gelten. Ein Stage0-smith führt die Werkzeuge von Homebrew aus, oder $SMITH_CLANG_FORMAT, $SMITH_CLANG_TIDY, $SMITH_CLANGD.
smiths Voreinstellungen, wenn ein Projekt keine Datei hat (Issue #43). Ein Projekt ohne .clang-format (oder _clang-format) und ohne .clang-tidy, die von jedem Dateiordner und aufwärts gesucht werden, wie es clang-format und clang-tidy tun, wird mit smiths eigenen, in smith eingebetteten (den Dateien, die smith new heute schreibt) formatiert und gelintet; es gibt nichts zu schreiben. Eine Datei im Projekt ersetzt smiths gesamte, niemals zusammengeführt, und ein explizites --style (oder --fallback-style), --config oder --config-file gewinnt. Bei Standardeingabe gibt --assume-filename an, wo gesucht werden soll. Das Benennen von Dateien mit und ohne eine Projektdatei in einem Befehl funktioniert (smith führt die zweite Art als einen anderen Prozess aus). smith fmt --dump-config > .clang-format und smith lint --dump-config > .clang-tidy geben die effektive Konfiguration aus (die des Projekts, sonst smiths), sodass ein Projekt die Voreinstellungen übernimmt, indem es sie ausgibt und bearbeitet, was es möchte; die Voreinstellungen ändern sich selten und absichtlich, sodass ein Projekt, das sie fixiert haben möchte, sie ausgibt. smith schreibt seine Kopie nach $XDG_DATA_HOME/smith/defaults/ (sonst ~/.local/share/...). smith cc ist nie betroffen: Es bleibt ein reiner Passthrough.
.smith-Dateien
smith fmt x.smith (und -i, --dry-run, Standardeingabe mit --assume-filename=x.smith) formatiert eine .smith-Datei als C, wobei ihre ::-Pfade, module a::b;- und import a::b as x;-Zeilen sowie import <sys/wait.h>; ganz erhalten bleiben; smith fmt ohne Argumente formatiert auch die .smith-Dateien des Projekts (git sieht sie). import und module innerhalb einer Funktion sind Namen, wie in C. Benötigt einen smith, dessen clang-format den .smith-Patch hat (ein Stage0 führt Homebrews aus, das .smith als C++ liest und daher C-Namen, die C++-Schlüsselwörter sind, wie throw falsch liest). clangd formatiert .smith-Dateien auf dieselbe Weise.
smith lint x.smith -- <flags> (clang-tidy, mit dem .clang-tidy des Projekts) lintet eine .smith-Datei, wie smith cc sie liest (-x c und -std=gnu2y, es sei denn, du nennst einen Standard; ein Compile-Datenbank-eigener Befehl wird so verwendet, wie er ist), und meldet die Quelle, wie sie geschrieben ist: Befunde, Notizen und Fix-Its an den Zeilen und Spalten des .smith-Texts, mit den Namen wie geschrieben (area und Box im Modul, box::area, wo es importiert wird, niemals geometry_box_area). readability-identifier-naming beurteilt den geschriebenen Namen eines dateibereichsweiten Namens eines Moduls, sodass die Regeln der Vorlage (snake_case-Funktionen und -Variablen, PascalCase-Typen) für area und Box gelten, und --fix schreibt das Token in der Quelle um; die size-Typen (U32, I32), die Kopien der Prototypen durch die Senkung und die Header, die smith build schreibt, werden niemals gemeldet. Ein Befund über einen Export wird in der Datei des Moduls gemeldet, nicht in jedem Importeur, und eine Korrektur dort benennt die Importeure nicht um. Andere Checks zeigen die geschriebenen Namen in ihren Nachrichten, aber ein Check, der den Namen selbst vergleicht (ein Längen- oder reservierte-Namen-Check, z. B.) liest immer noch den gesenkten. Benötigt einen smith, dessen clang den Token-Hook hat (smith cc --smith-which x.smith sagt token-hook yes); ein Stage0 führt Homebrews clang-tidy aus, das .smith nicht lesen kann.
Ebenfalls in dieser Familie: smith-check-lints.