smith check, fmt, lint 및 lsp
smith fmt, smith lint 및 smith lsp는 clang-format, clang-tidy 및 clangd로, 컴파일러와 동일한 LLVM에서 smith로 연결되어 모든 머신에서 동일하게 포매팅 및 린트합니다.
프로젝트 수준: 인자 없음
동사는 모든 프로젝트에서 동일한 의미를 가지며 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에 이름이 지정된 파일(생성된parser.c, 픽스처)은 건드리지 않습니다. Git 저장소 외부에서는 파일 이름을 지정하라고 메시지를 출력합니다 (smith fmt -i <files>).smith lint는 컴파일이 읽는 것(생성된 헤더)을 빌드한 다음,.clang-tidy를 사용하여 빌드의 컴파일 중 프로젝트 자체 소스(smith_object및 빌드가 컴파일하지 않는 소스의smith_compile_command)에 대해 clang-tidy를 실행합니다..smith/,build/출력물 또는 패키지는 제외됩니다. 모든.smith소스는smith lint x.smith -- <flags>와 동일하게 린트됩니다: 빌드 자체의 소스는 해당 컴파일 명령과 함께, git이 보는 다른 각.smith파일은 가장 가까운 컴파일 명령과 함께 린트되며,.clang-format-ignore에 이름이 지정된 파일은 제외됩니다(일반 소스가 아닌 파일의 목록: 테스트 입력, 의도적으로 잘못된 픽스처, 생성 및 복사된 파일;smith fmt도 이것을 읽으므로 두 번째 목록은 없습니다). 발견사항이 있으면 린트가 실패합니다. 마지막 줄에는linted N files라고 표시됩니다(smith check:lint ok: N files)..smith소스가 있는 프로젝트에서 하나도 린트하지 않으면 실패합니다. 폴더에 있는.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). 네트워크에서 제공되지 않는 패키지(클라우드 샌드박스의 tree-sitter 파서)를 기다리는 파일은 이름으로 건너뜁니다(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의 드라이 런), docs, lint, test, prove를 순서대로 실행하며, 실패해도 멈추지 않습니다: 각 부분은 한 줄을 출력합니다: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이며 성공으로 간주; 낮은 커버리지로 실패하지 않음). 각 부분의 줄은 벽시계 및 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칸 공백, 한 줄에 하나의 문장,#주석 유지). 구문 분석 오류가 있는 새 구문 파일은path:line:column: message로 보고되며, 바이트 단위로 그대로 유지되고(--dry-run에서도),smith fmt가 exit 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는 노이즈였던 두 가지 분석기 검사를 끕니다(게임, 학습자 및 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 철자로: 하나의 수정사항에 대한 편집은 함께 적용되거나 전혀 적용되지 않으며, 겹치는 수정사항은 건너뛰고, 파일은 더 이상 적용할 것이 없을 때까지 다시 구문 분석되며, 최대 16회). path: N fixes applied를 출력합니다. 두 번째 실행은 0 fixes applied를 출력합니다. .smith 파일만 읽으며 전체 smith가 필요합니다. -- <flags>와 함께 사용하면 clang-tidy의 --fix입니다(위 참조). 아직 어떤 구문 분석 오류도 수정사항을 제공하지 않습니다: 오래된 형식은 각 티켓별로 수정사항을 얻습니다(#1428).
smith lint FILE은 해당 폴더가 존재할 때 --extra-arg=-I를 build/<os>/front-project/.smith/include에 추가하고(프론트 모듈이 이를 통해 서로 가져오기), macOS가 아닌 호스트에서는 한 줄을 출력합니다: CI는 Mac에서 린트하며, 여기서 u64는 unsigned long long이고 usize는 unsigned long이므로, usize가 있는 (U64)(i + 1)은 거기서만 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의 기본값 (이슈 #43). .clang-format(또는 _clang-format) 및 .clang-tidy가 없는 프로젝트는 각 파일의 폴더에서 위로(clang-format 및 clang-tidy가 하는 대로) 조회되며, smith에 내장된 smith 자체의 것으로 포매팅 및 린트됩니다(smith new가 오늘날 작성하는 파일). 작성할 것이 없습니다. 프로젝트의 파일은 smith의 전체를 대체하며(병합되지 않음), 명시적인 --style(또는 --fallback-style), --config 또는 --config-file이 우선합니다. 표준 입력의 경우 --assume-filename은 조회할 위치를 지정합니다. 하나의 명령에서 프로젝트 파일이 있는 파일과 없는 파일을 함께 지정할 수 있습니다(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에서와 같이 이름입니다. .smith 패치가 있는 clang-format이 있는 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은 모듈의 파일 범위 이름에 대해 작성된 이름을 판단하므로, 템플릿의 규칙(snake_case 함수 및 변수, PascalCase 타입)이 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.