smith check, fmt, lint y lsp
smith fmt, smith lint y smith lsp son clang-format, clang-tidy y clangd, enlazados en smith desde el mismo LLVM que el compilador, de modo que cada máquina formatea y lintiza igual.
Sobre el proyecto: sin argumentos
Los verbos significan lo mismo en cada proyecto y leen lo que declara su build.c; un proyecto no escribe ninguna tarea para ellos.
smith fmtreescribe cada archivo C, C++, Objective-C y.smithque git ve (rastreados, y no rastreados pero no ignorados;.c .h .m .mm .cpp .cc .cxx .hpp .hh .smith .metal) según.clang-format(un archivo.metalse formatea como C++, el lenguaje que clang-format da a una extensión que no conoce).smith fmt --dry-run(o-n, con--Werroro-i) ysmith lint --quiettambién son las formas de proyecto: solo opciones, sin nombres de archivo, por lo que nunca esperan entrada estándar; cualquier otra opción o un nombre de archivo los convierte en las herramientas (smith fmt --assume-filename=x.clee la entrada estándar). Un archivo nombrado en.clang-format-ignore(clang-format lo lee por sí mismo: unparser.cgenerado, un fixture) se deja intacto. Fuera de un repositorio git, indica que se den nombres a los archivos (smith fmt -i <files>).smith lintconstruye lo que los compiladores leen (encabezados generados), luego ejecuta clang-tidy con.clang-tidysobre las fuentes propias del proyecto entre las compilaciones de la construcción (smith_object, ysmith_compile_commandpara fuentes que la construcción nunca compila), lado a lado. No sobre.smith/, salidas debuild/o paquetes. Cada fuente.smithse lintiza comosmith lint x.smith -- <flags>: las propias de la construcción con su comando de compilación, y cada otro archivo.smithque git ve con el comando de compilación más cercano, excepto lo que nombra.clang-format-ignore(la única lista de archivos que no son fuente ordinaria: entradas de prueba, fixtures deliberadamente incorrectos, archivos generados y copiados;smith fmttambién lo lee, por lo que no hay una segunda lista). Un hallazgo hace fallar el lint; su última línea dicelinted N files(smith check:lint ok: N files), y un proyecto con fuentes.smithque no lintiza ninguna falla. Un.clang-tidyen una carpeta (comoInheritParentConfig: truecon otras verificaciones) se aplica allí.smith lintes incremental: el resultado de clang-tidy para un archivo se almacena en caché bajo~/.cache/smith/linty se reproduce mientras el archivo, lo que incluye (para un archivo.smith, también los encabezados generados de los módulos que importa), su.clang-tidyy smith no cambien, por lo que la última línea leesmith lint: linted 180 files (3 run, 177 cached, 1.2 s)y un árbol sin cambios no ejecuta clang-tidy sobre ningún archivo.SMITH_LINT_CACHE=0lo desactiva,SMITH_LINT_CACHE=whydice por qué se ejecutó un archivo,smith cache clean lintlo vacía. Un archivo cuyo clang-tidy falla se nombra en las últimas líneas (smith lint: c.c: exited with status 1, owas killed by signal 9, que no imprime nada propio) y al final de su propia salida.smith lint --changed[=<ref>]lintiza solo los archivos cambiados desde la merge-base con<ref>(por defecto: el upstream de la rama, si no la rama deorigin/HEADoorigin/main, nunca unmainlocal; si ninguno de ellos es un error, nombre--changed=<ref>; la línea que imprime nombra la base; las ediciones y los archivos no rastreados cuentan) y los archivos que los incluyen o importan; un.clang-tidy, archivo de construcción,shim/opatches/cambiado selecciona cada archivo, y nada afectado lo dice y tiene éxito. También construye solo lo que esos archivos esperan. El simplesmith lintlintiza todo (CI). Un archivo que espera un paquete que la red no proporciona (el parser tree-sitter en un sandbox de nube) se omite por nombre (smith lint: skipped runtime/tree_sitter_data.c: the tree-sitter parser it embeds cannot be fetched (<url>)) y el resto se lintiza; CI (CIoSMITH_PRIORITY=ci) falla en su lugar.smith lint FILEen un proyecto aún no construido (sincompile_commands.json) se detiene y dice que ejecutesmith build smith_needsuna vez, en lugar de informar los encabezados generados faltantes como errores.smith docsverificaknowledge/y los skills (smith-docs).smith checkejecuta fmt (dry-run de clang-format), docs, lint, test y prove, en ese orden, y no se detiene ante un fallo: cada parte imprime una línea,smith check: <part> ok: <detail> (<n> s wall, <n> s cpu)oFAILED (status N)con un extracto acotado del fallo y la ruta del registro completo (.smith/log/<part>.log; la salida de una parte que pasa también está allí;smith check -vimprime todo a medida que ocurre), luegosmith check: promises: N(lo que smith confía, de una construcción predeterminada que realiza si es necesario), y la última línea essmith check: okosmith check: failed: <parts>; el código de salida es 1 cuando alguno falla. La línea de prove dice la cobertura,smith check: prove ok (4 of 23 functions): ...(funciones con un contrato propio, del proyecto;0 of N functionscuando no hay nada que probar, lo que es un éxito; nada falla por baja cobertura). La línea de cada parte termina con su tiempo wall y CPU ((91.2 s wall, 480.1 s cpu): CPU es usuario más sistema, de la parte y los procesos que esperó). No acepta argumentos excepto opciones-Dy-v. En un host que no sea macOS ejecuta las pruebas con--skip-macosy lo dice (the macOS-only tests do not run on this host).smith testtermina con una tabla de las tareas de la construcción (pasos de.smith/task/<name>, como los propiostest-<name>de smith), primero las más lentas: segundos wall, CPU y sistema y el número de procesos smith que cada una inició (SMITH_START_LOG, que smith añade al comenzarmain; una tarea que limpia el entorno no se cuenta); las ocho más lentas, cada tarea consmith check -voSMITH_ACCOUNT=all, ninguna conSMITH_ACCOUNT=no. Las tareas se ejecutan mediantesmith --smith-account <file> <name> <command...>, que escribe la línea.- Los archivos
.smithen la nueva sintaxis no son de clang-format (#1890, #1886, #2040):smith fmtenvía un archivo.smithal formateador propio de smith (front::format) a menos que esté en la sintaxis actual (una línea comienza con una forma que solo la sintaxis actual o C tiene, el parser actual lo lee sin error, o su primer error en la nueva sintaxis tiene una corrección, como un comentario//) o tenga un error de parseo y ninguna línea que solo la nueva sintaxis tenga (fn,let,pub,#): un estilo y ningún.clang-formatpara él (cualquier sangría consistente sale a 4 espacios, una declaración por línea, comentarios#mantenidos). Un archivo de nueva sintaxis con un error de parseo se reporta comopath:line:column: message, se deja byte por byte como estaba (con--dry-runtambién) y hace quesmith fmtsalga con 1: nunca se envía a clang-format, que lo destrozaría. Es idempotente, respeta.clang-format-ignore, y--dry-run/-nnombra los archivos que cambiarían (path: would be formatted) sin escribir. Un archivo.smithen la sintaxis actual (y cada.c) sigue siendo de clang-format hasta que el cambio (#1631) elimine ese respaldo. Probado portests/fmt_smith_test.smith. smith fmt FILErechaza un archivo cuya extensión no sea una de esas (un.sh, un.md), con un error que nombra el archivo y no escribe nada, ya que clang-format lo leería como C y lo corrompería;--assume-filename=x.cdice lo que es.- Antes de commit:
smith fmt, luegosmith check. - Una tarea propia (una verificación personalizada, un generador) es
smith_tasken build.c y se ejecuta consmith build <task>; ninguna tarea o alias puede llamarsefmt,lint,docs,prove,check,runotest.smith build checky los demás nombres de verbo se rechazan: use el verbo.
Sobre archivos: con argumentos
smith lint DIR (una carpeta entre los argumentos) lintiza las fuentes C, C++, Objective-C y .smith bajo ella que git ve y .clang-format-ignore no nombra, como el lint del proyecto (sin encabezados, que se leen a través de sus fuentes); smith lint front -- <flags> y smith lint front/ main.c se mezclan con archivos. Una carpeta sin dicha fuente es un error.
El analizador de clang-tidy (clang-analyzer-*) lee smith_requires, smith_ensures, smith_invariant y smith_assert de <smith/contract.h> como suposiciones (target::static_analyzer), por lo que un índice acotado por un contrato no es reportado por clang-analyzer-security.ArrayBound.
El .clang-tidy predeterminado de smith desactiva dos verificaciones del analizador que eran ruido (en game, learner y smith: 546 de 616 hallazgos): clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling (cada memcpy) y clang-analyzer-optin.performance.Padding. Active una de nuevo en el .clang-tidy propio del proyecto (smith lint --dump-config > .clang-tidy escribe el archivo efectivo) eliminando su línea -clang-analyzer-....
smith lint --fix FILE.smith... (sin --) aplica las correcciones que el propio front-end de smith lleva en sus errores de parseo (una forma antigua o de estilo C con su ortografía smith: las ediciones de una corrección se aplican juntas o no se aplican, una corrección superpuesta se omite, y un archivo se parsea de nuevo hasta que nada se aplica, como máximo 16 pasadas) e imprime path: N fixes applied; una segunda ejecución imprime 0 fixes applied. Lee solo archivos .smith y necesita el smith completo. Con -- <flags> es --fix de clang-tidy, más arriba. Ningún error de parseo lleva aún una corrección: las formas antiguas reciben su corrección ticket por ticket (#1428).
smith lint FILE añade --extra-arg=-I para build/<os>/front-project/.smith/include cuando esa carpeta existe (los módulos front se importan entre sí a través de ella), y en un host que no sea macOS imprime una línea: CI lintiza en un Mac, donde u64 es unsigned long long y usize es unsigned long, por lo que (U64)(i + 1) con un usize es un hallazgo bugprone-misplaced-widening-cast allí solamente; corrija dicho casteo escribiendo (U64)i + 1.
Con argumentos son las herramientas: smith fmt main.c reescribe el archivo en su lugar (clang-format lo imprimiría; smith añade -i cuando nombra archivos y ninguna opción elige otro modo: -n, --dry-run, --lines, --assume-filename mantienen el significado de clang-format, y smith fmt --assume-filename=x.c < x.c imprime el resultado), smith fmt --dry-run --Werror main.c, smith fmt --dry-run --Werror main.c, smith lint --quiet main.c -- <flags>, smith lsp --check=main.c. Se aplican .clang-format y .clang-tidy del proyecto. Un smith stage0 ejecuta las herramientas de Homebrew, o $SMITH_CLANG_FORMAT, $SMITH_CLANG_TIDY, $SMITH_CLANGD.
Valores predeterminados de smith, donde un proyecto no tiene archivo (issue #43). Un proyecto sin .clang-format (o _clang-format) y sin .clang-tidy, buscados desde la carpeta de cada archivo hacia arriba como hacen clang-format y clang-tidy, se formatea y lintiza con los propios de smith, incrustados en smith (los archivos que smith new escribe hoy); no hay nada que escribir. Un archivo en el proyecto reemplaza el completo de smith, nunca fusionado, y un --style (o --fallback-style), --config o --config-file explícito gana. Con entrada estándar, --assume-filename nombra dónde buscar. Nombrar archivos con y sin un archivo de proyecto en un solo comando funciona (smith ejecuta el segundo tipo como otro proceso). smith fmt --dump-config > .clang-format y smith lint --dump-config > .clang-tidy imprimen el efectivo (el del proyecto, si no el de smith), por lo que un proyecto toma los valores predeterminados volcándolos y edita lo que desea; los valores predeterminados cambian raramente y con propósito, por lo que un proyecto que los quiere fijos los vuelca. smith escribe su copia en $XDG_DATA_HOME/smith/defaults/ (si no ~/.local/share/...). smith cc nunca se ve afectado: sigue siendo un paso puro.
Archivos .smith
smith fmt x.smith (y -i, --dry-run, entrada estándar con --assume-filename=x.smith) formatea un archivo .smith como C, con sus rutas ::, líneas module a::b; e import a::b as x; y import <sys/wait.h>; mantenidas completas; smith fmt sin argumentos formatea también los archivos .smith del proyecto (git los ve). import y module dentro de una función son nombres, como en C. Necesita un smith cuyo clang-format tenga el parche .smith (un stage0 ejecuta el de Homebrew, que lee .smith como C++ y por lo tanto lee mal nombres C que son palabras clave de C++, como throw). clangd formatea archivos .smith de la misma manera.
smith lint x.smith -- <flags> (clang-tidy, con el .clang-tidy del proyecto) lintiza un archivo .smith como smith cc lo lee (-x c, y -std=gnu2y a menos que nombre un estándar; el comando propio de una base de datos de compilación se usa tal cual) e informa como está escrita la fuente: hallazgos, notas y correcciones en las líneas y columnas del texto .smith, con los nombres tal como están escritos (area y Box en el módulo, box::area donde se importa, nunca geometry_box_area). readability-identifier-naming juzga el nombre escrito de los nombres de ámbito de archivo de un módulo, por lo que las reglas de la plantilla (funciones y variables en snake_case, tipos en PascalCase) se aplican a area y Box, y --fix reescribe el token en la fuente; los tipos con tamaño (U32, I32), las copias de prototipos de la bajada y los encabezados que smith build escribe nunca se reportan. Un hallazgo sobre una exportación se reporta en el archivo del módulo, no en cada importador, y una corrección allí no renombra a los importadores. Otras verificaciones muestran los nombres escritos en sus mensajes, pero una verificación que compara el nombre en sí (una verificación de longitud o de nombre reservado, por ejemplo) aún lee el bajado. Necesita un smith cuyo clang tenga el hook de token (smith cc --smith-which x.smith dice token-hook yes); un stage0 ejecuta el clang-tidy de Homebrew, que no puede leer .smith.
También en esta familia: smith-check-lints.