@atlisp/lint 0.2.9 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/atlisp-lint.default.json +2 -1
- package/atlisp-lint.schema.json +2 -1
- package/dist/checks/builtin-arg-count.js +1 -1
- package/dist/config.js +3 -2
- package/dist/locale.js +2 -0
- package/dist/presets.js +4 -2
- package/dist/rules.js +6 -0
- package/dist/validate.js +1 -0
- package/dist/visitor-runner.js +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -128,6 +128,7 @@ npx @atlisp/lint --format-check
|
|
|
128
128
|
| `shadow_builtin` | warn | 最佳实践 | defun 覆盖内置函数 |
|
|
129
129
|
| `dynamic_doc` | warn | 最佳实践 | C: 命令缺少 (princ) |
|
|
130
130
|
| `open_without_close` | warn | 最佳实践 | open/close 数量不匹配 |
|
|
131
|
+
| `strcat_or_arg` | error | 正确性 | strcat 参数中使用 or(or 返回 T/nil) |
|
|
131
132
|
| `strcat_usage` | warn | 最佳实践 | + 拼接而非 strcat |
|
|
132
133
|
| `cond_simplify` | warn | 风格 | 单分支 cond 可简化为 if |
|
|
133
134
|
| `arg_count` | warn | 最佳实践 | 参数数量不匹配 |
|
package/atlisp-lint.default.json
CHANGED
|
@@ -59,13 +59,14 @@
|
|
|
59
59
|
"extra_parens": "warn",
|
|
60
60
|
"arg_count": "error",
|
|
61
61
|
"builtin_arg_count": "error",
|
|
62
|
+
"strcat_or_arg": "error",
|
|
62
63
|
"strcat_usage": "warn",
|
|
63
64
|
"cond_simplify": "warn",
|
|
64
65
|
"quote_style": "warn",
|
|
65
66
|
"eq_usage": "warn",
|
|
66
67
|
"lambda_syntax": "off",
|
|
67
68
|
"comment_style": "warn",
|
|
68
|
-
"empty_catch": "
|
|
69
|
+
"empty_catch": "info",
|
|
69
70
|
"nth_usage": "warn",
|
|
70
71
|
"append_single": "warn",
|
|
71
72
|
"setq_multiple": "warn",
|
package/atlisp-lint.schema.json
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"duplicate_defun": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
60
60
|
"dynamic_doc": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
61
61
|
"empty_branch": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
62
|
-
"empty_catch": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "
|
|
62
|
+
"empty_catch": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
63
63
|
"empty_comment": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
64
64
|
"encoding": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
65
65
|
"entget_in_loop": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
@@ -111,6 +111,7 @@
|
|
|
111
111
|
"shadow_builtin": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
112
112
|
"single_arg_and_or": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
113
113
|
"startapp": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
114
|
+
"strcat_or_arg": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
114
115
|
"strcat_usage": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
115
116
|
"string_concat_loop": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
116
117
|
"token_in_url": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
@@ -172,7 +172,7 @@ const BUILTIN_ARITY = {
|
|
|
172
172
|
trans: { min: 3, max: 4 },
|
|
173
173
|
// === Table/dictionary ===
|
|
174
174
|
tblobjname: { min: 2, max: 2 },
|
|
175
|
-
tblnext: { min:
|
|
175
|
+
tblnext: { min: 1, max: 2 },
|
|
176
176
|
tblsearch: { min: 2, max: 3 },
|
|
177
177
|
acad_colordlg: { min: 1, max: 3 },
|
|
178
178
|
// === ActiveX ===
|
package/dist/config.js
CHANGED
|
@@ -102,13 +102,14 @@ const DEFAULT_CONFIG = {
|
|
|
102
102
|
extra_parens: 'warn',
|
|
103
103
|
arg_count: 'warn',
|
|
104
104
|
builtin_arg_count: 'error',
|
|
105
|
+
strcat_or_arg: 'error',
|
|
105
106
|
strcat_usage: 'info',
|
|
106
107
|
cond_simplify: 'info',
|
|
107
108
|
quote_style: 'info',
|
|
108
109
|
eq_usage: 'warn',
|
|
109
110
|
lambda_syntax: 'off',
|
|
110
111
|
comment_style: 'info',
|
|
111
|
-
empty_catch: '
|
|
112
|
+
empty_catch: 'info',
|
|
112
113
|
nth_usage: 'info',
|
|
113
114
|
append_single: 'info',
|
|
114
115
|
setq_multiple: 'warn',
|
|
@@ -120,7 +121,7 @@ const DEFAULT_CONFIG = {
|
|
|
120
121
|
shadow_builtin: 'warn',
|
|
121
122
|
dynamic_doc: 'warn',
|
|
122
123
|
loop_optimization: 'info',
|
|
123
|
-
format_indent: '
|
|
124
|
+
format_indent: 'off',
|
|
124
125
|
redundant_if: 'info',
|
|
125
126
|
unused_catch_result: 'info',
|
|
126
127
|
string_concat_loop: 'info',
|
package/dist/locale.js
CHANGED
|
@@ -94,6 +94,7 @@ const messages = {
|
|
|
94
94
|
'index.watch_status': '{0} files checked: {1} error(s), {2} warning(s)',
|
|
95
95
|
'index.format_unstable': 'Formatting is not idempotent — re-running formatCode produces different output',
|
|
96
96
|
unused_catch_result: 'vl-catch-all-apply result used as boolean — use vl-catch-all-error-p to check',
|
|
97
|
+
strcat_or_arg: 'or in strcat argument — or returns T/nil, not a string',
|
|
97
98
|
string_concat_loop: 'String concatenation inside {0} — move strcat outside the loop for performance',
|
|
98
99
|
if_without_else: 'if without else branch — else is implicitly nil, which is idiomatic in Lisp',
|
|
99
100
|
redundant_list: '(list) evaluates to nil — use nil directly',
|
|
@@ -222,6 +223,7 @@ Options:
|
|
|
222
223
|
'index.watch_status': '已检查 {0} 个文件: {1} 个错误, {2} 个警告',
|
|
223
224
|
'index.format_unstable': '格式化结果不稳定——再次格式化后输出不同',
|
|
224
225
|
unused_catch_result: 'vl-catch-all-apply 的结果被当作布尔值使用——应用 vl-catch-all-error-p 检查',
|
|
226
|
+
strcat_or_arg: 'strcat 参数中使用了 or 函数调用(or 返回 T 或 nil,不是字符串)',
|
|
225
227
|
string_concat_loop: '循环 {0} 内使用了字符串拼接——为提升性能请将 strcat 移到循环外',
|
|
226
228
|
if_without_else: 'if 没有 else 分支——else 默认为 nil 是 Lisp 惯用写法',
|
|
227
229
|
redundant_list: '(list) 等于 nil——请直接使用 nil',
|
package/dist/presets.js
CHANGED
|
@@ -50,13 +50,14 @@ exports.PRESETS = {
|
|
|
50
50
|
extra_parens: 'warn',
|
|
51
51
|
arg_count: 'warn',
|
|
52
52
|
builtin_arg_count: 'error',
|
|
53
|
+
strcat_or_arg: 'error',
|
|
53
54
|
strcat_usage: 'info',
|
|
54
55
|
cond_simplify: 'info',
|
|
55
56
|
quote_style: 'info',
|
|
56
57
|
eq_usage: 'warn',
|
|
57
58
|
lambda_syntax: 'off',
|
|
58
59
|
comment_style: 'info',
|
|
59
|
-
empty_catch: '
|
|
60
|
+
empty_catch: 'info',
|
|
60
61
|
nth_usage: 'info',
|
|
61
62
|
append_single: 'info',
|
|
62
63
|
setq_multiple: 'warn',
|
|
@@ -133,6 +134,7 @@ exports.PRESETS = {
|
|
|
133
134
|
extra_parens: 'error',
|
|
134
135
|
arg_count: 'error',
|
|
135
136
|
builtin_arg_count: 'error',
|
|
137
|
+
strcat_or_arg: 'error',
|
|
136
138
|
strcat_usage: 'error',
|
|
137
139
|
cond_simplify: 'error',
|
|
138
140
|
quote_style: 'error',
|
|
@@ -151,7 +153,7 @@ exports.PRESETS = {
|
|
|
151
153
|
shadow_builtin: 'error',
|
|
152
154
|
dynamic_doc: 'error',
|
|
153
155
|
loop_optimization: 'warn',
|
|
154
|
-
format_indent: '
|
|
156
|
+
format_indent: 'off',
|
|
155
157
|
redundant_if: 'error',
|
|
156
158
|
module_registration: 'error',
|
|
157
159
|
namespace_header: 'error',
|
package/dist/rules.js
CHANGED
|
@@ -179,6 +179,12 @@ exports.RULES = [
|
|
|
179
179
|
{ name: 'shadow_builtin', defaultSeverity: 'warn', description: '检测覆盖内置函数的 defun', category: '最佳实践' },
|
|
180
180
|
{ name: 'single_arg_and_or', defaultSeverity: 'info', description: '检测单参数 and/or 建议简化', category: '风格' },
|
|
181
181
|
{ name: 'startapp', defaultSeverity: 'warn', description: '检测 startapp 调用(启动外部程序)', category: '安全' },
|
|
182
|
+
{
|
|
183
|
+
name: 'strcat_or_arg',
|
|
184
|
+
defaultSeverity: 'error',
|
|
185
|
+
description: '检测 strcat 参数中使用 or(or 返回 T/nil,非字符串)',
|
|
186
|
+
category: '正确性',
|
|
187
|
+
},
|
|
182
188
|
{
|
|
183
189
|
name: 'strcat_usage',
|
|
184
190
|
defaultSeverity: 'info',
|
package/dist/validate.js
CHANGED
package/dist/visitor-runner.js
CHANGED
|
@@ -664,6 +664,29 @@ function runChecksWithVisitor(ast, file, config, disableMap) {
|
|
|
664
664
|
}
|
|
665
665
|
});
|
|
666
666
|
}
|
|
667
|
+
// strcat_or_arg
|
|
668
|
+
if (checks['strcat_or_arg'] !== 'off') {
|
|
669
|
+
visitor.on('*', node => {
|
|
670
|
+
if (node.type === 'list' &&
|
|
671
|
+
node.children &&
|
|
672
|
+
node.children.length > 1 &&
|
|
673
|
+
node.children[0].type === 'symbol' &&
|
|
674
|
+
node.children[0].name === 'strcat') {
|
|
675
|
+
if (isInQuote(node))
|
|
676
|
+
return;
|
|
677
|
+
for (let i = 1; i < node.children.length; i++) {
|
|
678
|
+
const arg = node.children[i];
|
|
679
|
+
if (arg.type === 'list' &&
|
|
680
|
+
arg.children &&
|
|
681
|
+
arg.children.length > 0 &&
|
|
682
|
+
arg.children[0].type === 'symbol' &&
|
|
683
|
+
arg.children[0].name === 'or') {
|
|
684
|
+
addIssue('strcat_or_arg', arg.pos.line, (0, locale_1.t)('strcat_or_arg'));
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
667
690
|
// redundant_list
|
|
668
691
|
if (checks['redundant_list'] !== 'off') {
|
|
669
692
|
visitor.on('list', node => {
|