smith check, fmt, lint et lsp
smith fmt, smith lint et smith lsp sont clang-format, clang-tidy et clangd, liés dans smith depuis le même LLVM que le compilateur, de sorte que chaque machine formate et analyse de la même manière.
Sur le projet : sans arguments
Les verbes signifient la même chose dans chaque projet et lisent ce que son build.c déclare ; un projet n'écrit aucune tâche pour eux.
smith fmtréécrit chaque fichier C, C++, Objective-C et.smithque git voit (suivi, et non suivi mais non ignoré ;.c .h .m .mm .cpp .cc .cxx .hpp .hh .smith .metal) selon.clang-format(un fichier.metalest formaté en C++, le langage que clang-format donne à une extension qu'il ne connaît pas).smith fmt --dry-run(ou-n, avec--Werrorou-i) etsmith lint --quietsont aussi les formes du projet : options seules, sans noms de fichiers, donc ils n'attendent jamais l'entrée standard ; toute autre option, ou un nom de fichier, en fait les outils (smith fmt --assume-filename=x.clit l'entrée standard). Un fichier nommé dans.clang-format-ignore(clang-format le lit lui-même : unparser.cgénéré, une fixture) est laissé tranquille. En dehors d'un dépôt git, il dit de nommer les fichiers (smith fmt -i <fichiers>).smith lintconstruit ce que les compilations lisent (en-têtes générés), puis exécute clang-tidy avec.clang-tidysur les sources propres du projet parmi les compilations de la construction (smith_object, etsmith_compile_commandpour les sources que la construction ne compile jamais), côte à côte. Pas.smith/, les sortiesbuild/ou les paquets. Chaque source.smithest analysée commesmith lint x.smith -- <flags>le fait : celles de la construction avec leur propre commande de compilation, et chaque autre fichier.smithque git voit avec la commande de compilation la plus proche, sauf ce que.clang-format-ignorenomme (la seule liste de fichiers qui ne sont pas des sources ordinaires : entrées de test, fixtures délibérément erronées, fichiers générés et copiés ;smith fmtla lit aussi, donc il n'y a pas de deuxième liste). Un résultat échoue à l'analyse ; sa dernière ligne ditlinted N fichiers(smith check:lint ok: N fichiers), et un projet avec des sources.smithqui n'en analyse aucune échoue. Un.clang-tidydans un dossier (commeInheritParentConfig: trueavec d'autres vérifications) s'y applique.smith lintest incrémental : le résultat de clang-tidy pour un fichier est mis en cache sous~/.cache/smith/lintet rejoué tant que le fichier, ce qu'il inclut (pour un fichier.smith, aussi les en-têtes générés des modules qu'il importe), son.clang-tidyet smith sont inchangés, donc la dernière ligne litsmith lint : analysés 180 fichiers (3 exécutés, 177 en cache, 1,2 s)et un arbre inchangé n'exécute clang-tidy sur aucun fichier.SMITH_LINT_CACHE=0le désactive,SMITH_LINT_CACHE=whydit pourquoi un fichier a été exécuté,smith cache clean lintle vide. Un fichier dont clang-tidy échoue est nommé dans les dernières lignes (smith lint : c.c : terminé avec le statut 1, oua été tué par le signal 9, ce qui n'affiche rien de propre) et à la fin de sa propre sortie.smith lint --changed[=<ref>]analyse seulement les fichiers modifiés depuis la base de fusion avec<ref>(par défaut : la branche amont, sinon la branche deorigin/HEADouorigin/main, jamais unemainlocale ; aucun d'eux n'est une erreur nommant--changed=<ref>; la ligne qu'il affiche nomme la base ; les modifications et les fichiers non suivis comptent) et les fichiers qui les incluent ou les importent ; un.clang-tidy, fichier de construction,shim/oupatches/modifié sélectionne chaque fichier, et rien d'affecté le dit ainsi et réussit. De plus, il ne construit que ce que ces fichiers attendent.smith lintsimple analyse tout (CI). Un fichier qui attend un paquet que le réseau ne fournit pas (l'analyseur tree-sitter dans un sandbox cloud) est ignoré par son nom (smith lint : ignoré runtime/tree_sitter_data.c : l'analyseur tree-sitter qu'il intégre ne peut pas être récupéré (<url>)) et le reste est analysé ; CI (CIouSMITH_PRIORITY=ci) échoue à la place.smith lint FICHIERdans un projet pas encore construit (pas decompile_commands.json) s'arrête et dit d'exécutersmith build smith_needsune fois, plutôt que de signaler les en-têtes générés manquants comme des erreurs.smith docsvérifieknowledge/et les compétences (smith-docs).smith checkexécute fmt (dry-run de clang-format), docs, lint, test et prove, dans cet ordre, et ne s'arrête pas en cas d'échec : chaque partie affiche une ligne,smith check: <partie> ok: <détail> (<n> s mur, <n> s cpu)ouÉCHEC (statut N)avec un extrait limité de l'échec et le chemin du journal complet (.smith/log/<partie>.log; la sortie d'une partie réussie s'y trouve aussi ;smith check -vaffiche tout au fur et à mesure), puissmith check: promesses: N(ce que smith croit, à partir d'une construction par défaut qu'il effectue si nécessaire), et la dernière ligne estsmith check: okousmith check: échec: <parties>; le code de sortie est 1 quand l'une d'elles a échoué. La ligne prove dit la couverture,smith check: prove ok (4 sur 23 fonctions): ...(fonctions avec un contrat propre, du projet ;0 sur N fonctionsquand il n'y a rien à prouver, ce qui est un succès ; rien n'échoue sur une faible couverture). Chaque ligne de partie se termine par son temps mur et CPU ((91,2 s mur, 480,1 s cpu): CPU est le temps utilisateur plus système, de la partie et des processus qu'elle a attendus). Il ne prend pas d'arguments à part les options-Det-v. Sur un hôte qui n'est pas macOS, il exécute les tests avec--skip-macoset le dit (les tests spécifiques à macOS ne sont pas exécutés sur cet hôte).smith testse termine par un tableau des tâches de la construction (étapes.smith/task/<nom>, comme les proprestest-<nom>de smith), les plus lentes en premier : secondes mur, CPU et système et le nombre de processus smith que chacune a démarrés (SMITH_START_LOG, que smith ajoute lorsquemaincommence ; une tâche qui efface l'environnement n'est pas comptée) ; les huit plus lentes, chaque tâche avecsmith check -vouSMITH_ACCOUNT=all, aucune avecSMITH_ACCOUNT=no. Les tâches sont exécutées viasmith --smith-account <fichier> <nom> <commande...>, qui écrit la ligne.- Les fichiers
.smithdans la nouvelle syntaxe ne sont pas du ressort de clang-format (#1890, #1886, #2040) :smith fmtenvoie un fichier.smithau propre formateur de smith (front::format) sauf s'il est dans la syntaxe actuelle (une ligne commence par une forme que seules la syntaxe actuelle ou C possèdent, l'analyseur actuel le lit sans erreur, ou sa première erreur dans la nouvelle syntaxe a un correctif, comme un commentaire//) ou a une erreur d'analyse et aucune ligne que seule la nouvelle syntaxe a (fn,let,pub,#) : un seul style et pas de.clang-formatpour lui (toute indentation cohérente sort à 4 espaces, une instruction par ligne, commentaires#conservés). Un fichier en nouvelle syntaxe avec une erreur d'analyse est signalé parchemin:ligne:colonne: message, laissé octet pour octet tel quel (même avec--dry-run) et fait échouersmith fmtavec le code 1 : il n'est jamais envoyé à clang-format, qui le déformerait. Il est idempotent, respecte.clang-format-ignore, et--dry-run/-nnomme les fichiers qui changeraient (chemin: serait formaté) sans écrire. Un fichier.smithdans la syntaxe actuelle (et chaque.c) reste du ressort de clang-format jusqu'à ce que le basculement (#1631) supprime ce recours. Testé partests/fmt_smith_test.smith. smith fmt FICHIERrefuse un fichier dont l'extension n'est pas l'une de celles-ci (un.sh, un.md), avec une erreur qui nomme le fichier et n'écrit rien, puisque clang-format le lirait comme du C et le corromprait ;--assume-filename=x.cdit ce qu'il est.- Avant de valider :
smith fmt, puissmith check. - Une tâche personnalisée (une vérification personnalisée, un générateur) est
smith_taskdans build.c et s'exécute avecsmith build <tâche>; aucune tâche ou alias ne peut être nomméfmt,lint,docs,prove,check,runoutest.smith build checket les autres noms de verbes sont refusés : utilisez le verbe.
Sur les fichiers : avec arguments
smith lint DOSSIER (un dossier parmi les arguments) analyse les sources C, C++, Objective-C et .smith sous celui-ci que git voit et que .clang-format-ignore ne nomme pas, comme l'analyse du projet (pas d'en-têtes, qui sont lues via leurs sources) ; smith lint front -- <flags> et smith lint front/ main.c se mélangent avec des fichiers. Un dossier sans telle source est une erreur.
L'analyseur de clang-tidy (clang-analyzer-*) lit smith_requires, smith_ensures, smith_invariant et smith_assert de <smith/contract.h> comme des hypothèses (target::static_analyzer), donc un index qu'un contrat borne n'est pas signalé par clang-analyzer-security.ArrayBound.
Le .clang-tidy par défaut de smith désactive deux vérifications de l'analyseur qui étaient du bruit (sur game, learner et smith : 546 sur 616 résultats) : clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling (chaque memcpy) et clang-analyzer-optin.performance.Padding. Réactivez-en une dans le propre .clang-tidy du projet (smith lint --dump-config > .clang-tidy écrit le fichier effectif) en supprimant sa ligne -clang-analyzer-....
smith lint --fix FICHIER.smith... (pas de --) applique les correctifs que le propre front-end de smith porte dans ses erreurs d'analyse (une forme ancienne ou de style C avec son orthographe smith : les modifications d'un correctif sont appliquées ensemble ou pas du tout, un correctif qui chevauche est ignoré, et un fichier est analysé à nouveau jusqu'à ce que rien ne s'applique, au plus 16 passages) et affiche chemin: N correctifs appliqués ; une deuxième exécution affiche 0 correctifs appliqués. Il lit uniquement les fichiers .smith et nécessite le smith complet. Avec -- <flags>, c'est le --fix de clang-tidy, ci-dessus. Aucune erreur d'analyse ne porte encore de correctif : les formes anciennes obtiennent leur ticket par ticket (#1428).
smith lint FICHIER ajoute --extra-arg=-I pour build/<os>/front-project/.smith/include quand ce dossier existe (les modules front s'importent mutuellement via lui), et sur un hôte qui n'est pas macOS affiche une ligne : CI analyse sur un Mac, où u64 est unsigned long long et usize est unsigned long, donc (U64)(i + 1) avec un usize est un résultat bugprone-misplaced-widening-cast uniquement là ; corrigez un tel cast en écrivant (U64)i + 1.
Avec des arguments, ce sont les outils : smith fmt main.c réécrit le fichier sur place (clang-format l'afficherait ; smith ajoute -i quand vous nommez des fichiers et qu'aucune option ne choisit un autre mode : -n, --dry-run, --lines, --assume-filename conservent le sens de clang-format, et smith fmt --assume-filename=x.c < x.c affiche le résultat), smith fmt --dry-run --Werror main.c, smith lint --quiet main.c -- <flags>, smith lsp --check=main.c. Le .clang-format et .clang-tidy du projet s'appliquent. Un smith stage0 exécute les outils de Homebrew, ou $SMITH_CLANG_FORMAT, $SMITH_CLANG_TIDY, $SMITH_CLANGD.
Les valeurs par défaut de smith, là où un projet n'a pas de fichier (problème #43). Un projet sans .clang-format (ou _clang-format) et sans .clang-tidy, recherchés à partir du dossier de chaque fichier et vers le haut comme le font clang-format et clang-tidy, est formaté et analysé avec ceux de smith, intégrés dans smith (les fichiers que smith new écrit aujourd'hui) ; il n'y a rien à écrire. Un fichier dans le projet remplace la totalité de ceux de smith, jamais fusionnée, et un --style (ou --fallback-style), --config ou --config-file explicite l'emporte. Avec l'entrée standard, --assume-filename nomme où chercher. Nommer des fichiers avec et sans fichier de projet dans une seule commande fonctionne (smith exécute le second type comme un autre processus). smith fmt --dump-config > .clang-format et smith lint --dump-config > .clang-tidy affichent la configuration effective (celle du projet, sinon celle de smith), donc un projet s'approprie les valeurs par défaut en les exportant et modifie ce qu'il veut ; les valeurs par défaut changent rarement et intentionnellement, donc un projet qui les veut fixes les exporte. smith écrit sa copie dans $XDG_DATA_HOME/smith/defaults/ (sinon ~/.local/share/...). smith cc n'est jamais affecté : il reste un pur passage.
Fichiers .smith
smith fmt x.smith (et -i, --dry-run, l'entrée standard avec --assume-filename=x.smith) formate un fichier .smith en C, avec ses chemins ::, les lignes module a::b; et import a::b as x; et import <sys/wait.h>; conservées intégralement ; smith fmt sans arguments formate aussi les fichiers .smith du projet (git les voit). import et module à l'intérieur d'une fonction sont des noms, comme en C. Nécessite un smith dont clang-format a le correctif .smith (un stage0 exécute celui de Homebrew, qui lit .smith comme du C++ et donc interprète mal les noms C qui sont des mots-clés C++, comme throw). clangd formate les fichiers .smith de la même manière.
smith lint x.smith -- <flags> (clang-tidy, avec le .clang-tidy du projet) analyse un fichier .smith comme smith cc le lit (-x c, et -std=gnu2y sauf si vous nommez un standard ; la commande propre d'une base de données de compilation est utilisée telle quelle) et signale comme la source est écrite : résultats, notes et correctifs aux lignes et colonnes du texte .smith, avec les noms tels qu'écrits (area et Box dans le module, box::area là où il est importé, jamais geometry_box_area). readability-identifier-naming juge le nom écrit des noms au niveau du fichier d'un module, donc les règles du modèle (snake_case pour les fonctions et variables, PascalCase pour les types) s'appliquent à area et Box, et --fix réécrit le jeton dans la source ; les types dimensionnés (U32, I32), les copies d'abaissement des prototypes et les en-têtes que smith build écrit ne sont jamais signalés. Un résultat concernant une exportation est signalé dans le fichier du module, pas dans chaque importateur, et un correctif là ne renomme pas les importateurs. Les autres vérifications montrent les noms écrits dans leurs messages, mais une vérification qui compare le nom lui-même (une vérification de longueur ou de nom réservé, par exemple) lit encore celui abaissé. Nécessite un smith dont le clang a le crochet de jeton (smith cc --smith-which x.smith dit token-hook yes) ; un stage0 exécute le clang-tidy de Homebrew, qui ne peut pas lire .smith.
Appartient aussi à cette famille : smith-check-lints.