@atlisp/lint
v0.2.8
Published
AutoLISP static analysis tool — parens, security, conventions, SBCL syntax validation
Downloads
6,511
Maintainers
Readme
@atlisp/lint
AutoLISP 静态分析工具 — 括号匹配、安全检查、编码检测、命名规范、函数复杂度、跨文件分析、SBCL 语法校验。
安装
npm install -g @atlisp/lint需要 Node.js >= 18。SBCL 语法校验为可选功能,如需启用请安装 SBCL。
快速开始
# 在项目目录下初始化配置文件
npx @atlisp/lint --init
# 运行检查
npx @atlisp/lint
# 输出 JSON 格式
npx @atlisp/lint --format json
# 自动修复可修复问题
npx @atlisp/lint --fix
# 监听文件变化自动重检
npx @atlisp/lint --watch
# 自动格式化代码缩进
npx @atlisp/lint --format-code
# 检查代码格式(不修改文件)
npx @atlisp/lint --format-checkCLI 选项
--src <dir> 指定源码目录(可多次使用)
--test <dir> 指定测试目录(可多次使用)
--config <path> 指定配置文件路径
--staged 仅检查 git 暂存区中的 .lsp 文件
--format <format> 输出格式:default(默认)| json
--init 在当前目录生成 atlisp-lint.json
--install-hook 安装 git pre-commit hook
--fix 自动修复尾部空格、BOM、多余括号、冗余 progn/let、引号风格等问题
--cache 启用文件哈希缓存,跳过未变更的文件
--clear-cache 清除缓存目录
--parallel 开启多线程并行检查(使用 Worker Threads)
--project 启用跨文件分析(Phase 1b)
--sbcl 启用 SBCL 语法校验(Phase 2,需安装 SBCL)
--watch 监听模式,文件变动自动重新检查
--hook-args <args> 自定义 pre-commit hook 参数(配合 --install-hook)
--diff 仅检查自上次提交后变更的文件
--changed <branch> 仅检查相对于某分支有变更的文件(默认:main)
--help 显示帮助信息
--version 显示版本号
--format-code 自动格式化代码缩进(基于括号深度 + AST 对齐)
--format-check 只检查代码缩进格式(不修改文件,不符合则退出码 1)架构:三相检测
Phase 1a — 单文件静态检查(84 条规则)
所有 84 条规则在单文件范围内运行,支持 --parallel 多线程并行。
| 规则 | 默认 | 类别 | 说明 |
|------|------|------|------|
| parens | error | 语法 | 括号不匹配 |
| trailing_paren | warn | 语法 | 多余闭合括号 |
| extra_parens | warn | 语法 | 可疑的连续右括号 |
| encoding | error | 编码 | UTF-8 BOM 检查 / 非 UTF-8 编码 |
| quit_exit | error | 安全 | quit/exit 调用(会终止 CAD 进程) |
| command_shell | error | 安全 | command shell(命令注入风险) |
| startapp | warn | 安全 | startapp(启动外部程序) |
| vl_registry_write | warn | 安全 | vl-registry-write(修改注册表) |
| token_in_url | warn | 安全 | URL 中含 token=(凭据泄露) |
| vlax_without_loading | warn | 安全 | vlax-* 未调用 vl-load-com |
| cl_syntax | warn | 语法 | Common Lisp 特有语法(如 &key) |
| line_length | warn | 风格 | 行长度超过限制 |
| function_complexity | warn | 复杂度 | 函数行数或嵌套深度超限 |
| trailing_whitespace | warn | 风格 | 行尾多余空格 |
| empty_comment | warn | 风格 | 空注释行(只有 ; 没有内容) |
| parameter_naming | warn | 最佳实践 | 参数首字母大写 |
| unused_variable | warn | 最佳实践 | 变量赋值但未使用 |
| unused_parameter | warn | 最佳实践 | 参数从未使用 |
| unused_let_binding | warn | 最佳实践 | let 绑定从未使用 |
| unused_local_fun | warn | 最佳实践 | defun / 局部函数未使用 |
| missing_doc | warn | 风格 | 函数缺少注释说明 |
| error_handling | warn | 最佳实践 | 使用 command 但缺少 *error* 处理 |
| global_naming | warn | 风格 | 全局变量未用 *...* 命名 |
| constant_condition | warn | 风格 | if/while/cond 中常量条件 |
| redundant_progn | warn | 风格 | 分支中多余 progn |
| empty_branch | warn | 风格 | if/cond 中空分支 |
| redundant_if | warn | 风格 | if/when 中冗余 progn |
| redundant_let | warn | 风格 | 无绑定 let 建议改用 progn |
| redundant_quotes | warn | 风格 | 冗余双引号 ''x |
| redundant_setq | warn | 风格 | setq 赋值自身 |
| redundant_nil_else | warn | 风格 | if 中冗余 nil 分支 |
| single_arg_and_or | warn | 风格 | 单参数 and/or 可简化 |
| double_not | warn | 风格 | 双重 (not (not ...)) |
| multiple_setq | warn | 风格 | 连续 setq 可合并 |
| setq_multiple | warn | 风格 | 连续 setq 可合并 |
| setq_single_arg | warn | 正确性 | setq 缺少值 |
| assoc_without_cdr | warn | 正确性 | assoc 结果未用 cdr 提取 |
| identical_branches | warn | 正确性 | if 的 then/else 分支完全相同 |
| while_constant | warn | 正确性 | while 使用常量条件 |
| cond_duplicate | warn | 正确性 | cond 中存在重复条件 |
| recursive_call | warn | 正确性 | 函数自调用(可能无限递归) |
| self_compare | warn | 正确性 | 自比较表达式 |
| variable_shadow | warn | 最佳实践 | setq 覆盖 let 绑定的同名变量 |
| misplaced_else | warn | 风格 | (if (not ...) ...) 交换分支 |
| quote_vs_function | warn | 风格 | mapcar/apply 中用引用 lambda |
| commented_code | warn | 风格 | 被注释掉的代码 |
| quote_style | warn | 风格 | (quote ...) 建议缩写 |
| eq_usage | warn | 最佳实践 | eq 与数字比较 |
| lambda_syntax | warn | 风格 | (function (lambda ...)) 建议缩写 |
| comment_style | warn | 风格 | ; 后缺少空格 |
| empty_catch | warn | 最佳实践 | vl-catch-all-apply 未检查结果 |
| nth_usage | warn | 风格 | (nth 0 ...) 建议 car |
| append_single | warn | 风格 | (append (list ...)) 建议 cons |
| mixed_indent | warn | 风格 | 缩进混用 tab 和空格 |
| long_function_call | off | 风格 | 单行参数过多 |
| no_return | warn | 最佳实践 | 函数无返回值 |
| shadow_builtin | warn | 最佳实践 | defun 覆盖内置函数 |
| dynamic_doc | warn | 最佳实践 | C: 命令缺少 (princ) |
| open_without_close | warn | 最佳实践 | open/close 数量不匹配 |
| strcat_usage | warn | 最佳实践 | + 拼接而非 strcat |
| cond_simplify | warn | 风格 | 单分支 cond 可简化为 if |
| arg_count | warn | 最佳实践 | 参数数量不匹配 |
| bare_function_names | off | 风格 | defun 缺少命名空间前缀 |
| format_indent | off | 风格 | 代码缩进不符合格式化规范 |
| function_order | off | 最佳实践 | 定义在使用之后 |
| magic_number | off | 风格 | 硬编码魔法数字 |
| module_registration | off | 架构 | 模块文件未注册到 *modules* |
| namespace_header | off | 架构 | 缺少 (in-package ...) 头 |
| loop_optimization | off | 最佳实践 | 优化 while/assoc 循环 |
| builtin_arg_count | error | 正确性 | 内置函数调用参数个数不匹配 |
| unused_catch_result | info | 正确性 | vl-catch-all-apply 结果被当布尔值用 |
| string_concat_loop | info | 性能 | 循环内字符串拼接 |
| if_without_else | info | 风格 | if 无 else 分支 |
| redundant_list | info | 风格 | (list) 等价于 nil |
| entget_in_loop | warn | 性能 | 循环内 entget |
| promise_handler | info | 最佳实践 | vlax-invoke 缺少回调处理器 |
Phase 1b — 跨文件分析(--project)
通过 --project 启用,构建项目符号表后进行以下检查:
| 规则 | 默认 | 说明 |
|------|------|------|
| dangling_defun | warn | 函数定义但从未被任何文件调用 |
| missing_export | warn | 函数未注册到 @::*modules* |
| unused_package_dep | warn | 导入的包从未被引用 |
| module_cycle | warn | 模块循环依赖 |
| arg_count_project | warn | 跨文件检查函数参数数量 |
同时检测 duplicate_defun(函数名在多个文件中重复定义)。
Phase 2 — SBCL 语法校验(可选)
调用 SBCL 对每个 .lsp 文件做 Common Lisp reader 级别深度解析:
- 语法错误 — reader 无法解析的内容
- 符号未找到 — 未注册到 stub packages 中的符号
- CL-ism —
#(、#\、#.等 AutoLISP 无效语法 - defmacro — 默认不允许,除非文件在允许列表中
--format-code 代码格式化
基于括号深度自动调整代码缩进,规则:
- 每层嵌套增加 2 空格缩进
)单独一行时自动回到对应层级的缩进- 注释行按当前嵌套深度缩进
- 字符串中的括号不影响缩进计算
- 自动删除行尾多余空格
- 空行保持不变
- 格式化后进行幂等性检查,若再次格式化结果不一致则输出警告
# 格式化所有 .lsp 文件
npx @atlisp/lint --format-code
# 仅检查格式(不修改文件),不符合则退出码 1
npx @atlisp/lint --format-check--fix 自动修复
预扫描修复(fixFile)
| 规则 | 修复方式 |
|------|----------|
| trailing_whitespace | 删除行尾空格 |
| encoding (BOM) | 删除 UTF-8 BOM |
| trailing_paren | 删除多余闭合括号 |
| empty_comment | 删除空注释行 |
规则级修复(applyFixes)
| 规则 | 修复方式 |
|------|----------|
| redundant_quotes | ''x → 'x |
| double_not | (not (not ...)) → (not ...) |
| redundant_nil_else | (if cond x nil) → (if cond x) |
| single_arg_and_or | (and x) → x |
| redundant_setq | 删除 (setq x x) 行 |
| redundant_progn | 移除分支中多余的 (progn ...) 包装 |
| redundant_let | (let () ...) → (progn ...) |
| quote_style | (quote x) → 'x |
| redundant_if | 移除 if/when 分支中冗余 progn |
| misplaced_else | (if (not x) a b) → (if x b a) |
| format_indent | 对整个文件应用 formatCode() 修复缩进 |
行内忽略
在代码行尾添加注释可以忽略特定规则的检查:
(setq secret "token=abc123") ; atlisp-lint: disable=token_in_url配置文件
atlisp-lint.json:
{
"locale": "zh",
"source": {
"globs": ["**/*.lsp"],
"exclude": ["**/node_modules/**", "**/vendor/**", "**/.git/**"]
},
"checks": {
"parens": "error",
"encoding": "error",
"trailing_whitespace": "warn"
},
"preset": "recommended",
"line_length": {
"max": 200,
"tab_width": 2
},
"function_complexity": {
"max_lines": 300,
"max_nesting": 30
},
"cl_syntax": {
"keywords": ["&key"]
},
"dangerous_calls": {
"quit": "error",
"exit": "error",
"command_shell": "error",
"startapp": "warn",
"vl_registry_write": "warn"
},
"bare_function_names": {
"allowlist": ["T", "nil"],
"namespace_pattern": "^[a-z]+:"
},
"sbcl": {
"walk_exclude": [".vscode", "vendor", ".git"],
"defmacro_allow_files": ["compat-cl"]
}
}配置预设
通过 preset 字段选择预设,预设应用后再叠加用户配置(用户设置优先级最高):
| 预设 | 说明 |
|------|------|
| recommended | 推荐(默认值) |
| strict | 严格模式(大部分规则升为 error) |
| relaxed | 宽松模式(仅保留 4 条 error 规则) |
预设会覆盖 checks 中对应规则的默认值,用户可以在同一个文件中继续覆盖预设值。
目录级覆盖
在某个目录下放置 .atlisp-lint.json,该目录及其子目录中的文件会自动合并该覆盖配置。
{
"checks": {
"line_length": "off"
}
}多语言
支持中文和英文,通过配置文件 locale 字段切换:
{ "locale": "zh" } // 中文(默认)
{ "locale": "en" } // EnglishGit 集成
# 安装 pre-commit hook,每次提交前自动检查暂存文件
npx @atlisp/lint --install-hook
# 带自定义参数的 hook
npx @atlisp/lint --install-hook --hook-args "--config ci-config.json"
# 手动检查暂存文件
npx @atlisp/lint --staged缓存
# 启用缓存
npx @atlisp/lint --cache
# 清除缓存
npx @atlisp/lint --clear-cache基于文件内容 MD5 哈希缓存,跳过内容未变更的文件。
忽略文件
在项目根目录创建 .atlisp-lint-ignore,使用 gitignore 风格模式排除文件:
**/test/**
**/vendor/**开发
# 安装依赖
npm install
# 编译
npm run build
# 测试
npm test
# 运行所有检查
npm run format:check && npm run lint && npm run typecheck && npm test许可
MIT
