@atlisp/lint 0.1.23 → 0.1.25
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/atlisp-lint.default.json +2 -1
- package/dist/atlisp-lint.default.json +90 -0
- package/dist/checks/arg-count.js +1 -1
- package/dist/checks/assoc-without-cdr.js +1 -1
- package/dist/checks/builtin-arg-count.d.ts +3 -0
- package/dist/checks/builtin-arg-count.js +282 -0
- package/dist/checks/cond-duplicate.js +1 -1
- package/dist/checks/constant-condition.js +3 -3
- package/dist/checks/dangerous-calls.js +1 -1
- package/dist/checks/dangling-defun.js +1 -1
- package/dist/checks/double-not.js +1 -1
- package/dist/checks/empty-branch.js +1 -1
- package/dist/checks/empty-catch.js +1 -1
- package/dist/checks/function-complexity.js +1 -1
- package/dist/checks/global-naming.js +1 -1
- package/dist/checks/identical-branches.js +1 -1
- package/dist/checks/misplaced-else.js +1 -1
- package/dist/checks/multiple-setq.js +1 -1
- package/dist/checks/no-return.js +1 -1
- package/dist/checks/open-close.js +1 -1
- package/dist/checks/parameter-naming.js +1 -1
- package/dist/checks/quote-vs-function.js +1 -1
- package/dist/checks/recursive-call.js +1 -1
- package/dist/checks/redundant-let.js +1 -1
- package/dist/checks/redundant-nil-else.js +1 -1
- package/dist/checks/redundant-progn.js +1 -1
- package/dist/checks/redundant-quotes.js +1 -1
- package/dist/checks/redundant-setq.js +1 -1
- package/dist/checks/self-compare.js +1 -1
- package/dist/checks/setq-single-arg.js +1 -1
- package/dist/checks/single-arg-and-or.js +1 -1
- package/dist/checks/undeclared-setq.js +1 -1
- package/dist/checks/unused-catch-result.js +1 -1
- package/dist/checks/unused-let.js +1 -1
- package/dist/checks/unused-local-fun.js +1 -1
- package/dist/checks/unused-package-dep.js +1 -1
- package/dist/checks/unused-param.js +1 -1
- package/dist/checks/unused-variable.js +1 -1
- package/dist/checks/variable-shadow.js +1 -1
- package/dist/checks/while-constant.js +1 -1
- package/dist/formatters.d.ts +0 -1
- package/dist/formatters.js +0 -16
- package/dist/lib/lint-sbcl.lisp +161 -0
- package/dist/locale.js +2 -0
- package/dist/project.js +5 -5
- package/dist/rules.js +2 -1
- package/dist/runner.d.ts +0 -1
- package/dist/runner.js +150 -100
- package/dist/stub-packages.json +41 -0
- package/package.json +2 -2
package/atlisp-lint.default.json
CHANGED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"locale": "zh",
|
|
3
|
+
"source": {
|
|
4
|
+
"globs": ["**/*.lsp"],
|
|
5
|
+
"exclude": ["**/node_modules/**", "**/vendor/**", "**/.git/**"]
|
|
6
|
+
},
|
|
7
|
+
"checks": {
|
|
8
|
+
"parens": "error",
|
|
9
|
+
"encoding": "warn",
|
|
10
|
+
"cl_syntax": "warn",
|
|
11
|
+
"quit_exit": "error",
|
|
12
|
+
"command_shell": "error",
|
|
13
|
+
"startapp": "warn",
|
|
14
|
+
"vl_registry_write": "warn",
|
|
15
|
+
"vlax_without_loading": "off",
|
|
16
|
+
"token_in_url": "warn",
|
|
17
|
+
"open_without_close": "warn",
|
|
18
|
+
"bare_function_names": "off",
|
|
19
|
+
"line_length": "warn",
|
|
20
|
+
"function_complexity": "warn",
|
|
21
|
+
"parameter_naming": "warn",
|
|
22
|
+
"unused_variable": "warn",
|
|
23
|
+
"missing_doc": "warn",
|
|
24
|
+
"error_handling": "warn",
|
|
25
|
+
"global_naming": "warn",
|
|
26
|
+
"extra_parens": "warn",
|
|
27
|
+
"arg_count": "warn",
|
|
28
|
+
"strcat_usage": "warn",
|
|
29
|
+
"cond_simplify": "warn",
|
|
30
|
+
"redundant_progn": "warn",
|
|
31
|
+
"quote_style": "warn",
|
|
32
|
+
"eq_usage": "warn",
|
|
33
|
+
"lambda_syntax": "warn",
|
|
34
|
+
"comment_style": "warn",
|
|
35
|
+
"empty_catch": "warn",
|
|
36
|
+
"nth_usage": "warn",
|
|
37
|
+
"append_single": "warn",
|
|
38
|
+
"setq_multiple": "warn",
|
|
39
|
+
"function_order": "off",
|
|
40
|
+
"magic_number": "off",
|
|
41
|
+
"mixed_indent": "warn",
|
|
42
|
+
"long_function_call": "warn",
|
|
43
|
+
"no_return": "warn",
|
|
44
|
+
"shadow_builtin": "warn",
|
|
45
|
+
"dynamic_doc": "warn",
|
|
46
|
+
"loop_optimization": "off",
|
|
47
|
+
"type_check": "off",
|
|
48
|
+
"redundant_if": "warn",
|
|
49
|
+
"trailing_whitespace": "warn",
|
|
50
|
+
"module_registration": "off",
|
|
51
|
+
"namespace_header": "off"
|
|
52
|
+
},
|
|
53
|
+
"line_length": {
|
|
54
|
+
"max": 100,
|
|
55
|
+
"tab_width": 2
|
|
56
|
+
},
|
|
57
|
+
"function_complexity": {
|
|
58
|
+
"max_lines": 60,
|
|
59
|
+
"max_nesting": 6
|
|
60
|
+
},
|
|
61
|
+
"cl_syntax": {
|
|
62
|
+
"keywords": ["&key"]
|
|
63
|
+
},
|
|
64
|
+
"dangerous_calls": {
|
|
65
|
+
"quit": "error",
|
|
66
|
+
"exit": "error",
|
|
67
|
+
"command_shell": "error",
|
|
68
|
+
"startapp": "warn",
|
|
69
|
+
"vl_registry_write": "warn"
|
|
70
|
+
},
|
|
71
|
+
"module_registration": {
|
|
72
|
+
"severity": "off",
|
|
73
|
+
"patterns": [],
|
|
74
|
+
"dirs": ["modules"]
|
|
75
|
+
},
|
|
76
|
+
"namespace_header": {
|
|
77
|
+
"severity": "off",
|
|
78
|
+
"package": "",
|
|
79
|
+
"deps": [],
|
|
80
|
+
"search_lines": 15
|
|
81
|
+
},
|
|
82
|
+
"bare_function_names": {
|
|
83
|
+
"allowlist": ["T", "nil"],
|
|
84
|
+
"namespace_pattern": "^[a-z]+:"
|
|
85
|
+
},
|
|
86
|
+
"sbcl": {
|
|
87
|
+
"walk_exclude": [".vscode", "vendor", ".git"],
|
|
88
|
+
"defmacro_allow_files": ["compat-cl"]
|
|
89
|
+
}
|
|
90
|
+
}
|
package/dist/checks/arg-count.js
CHANGED
|
@@ -5,7 +5,7 @@ const locale_1 = require("../locale");
|
|
|
5
5
|
const parser_1 = require("@atlisp/parser");
|
|
6
6
|
function checkArgCount(content, file) {
|
|
7
7
|
const issues = [];
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
const defuns = (0, parser_1.astFindListWithHead)(ast, 'defun');
|
|
10
10
|
for (const defun of defuns) {
|
|
11
11
|
if (!defun.children || defun.children.length < 3)
|
|
@@ -5,7 +5,7 @@ exports.checkAssocWithoutCdrAst = checkAssocWithoutCdrAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkAssocWithoutCdr(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkAssocWithoutCdrAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkAssocWithoutCdrAst(ast, file) {
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkBuiltinArgCount = checkBuiltinArgCount;
|
|
4
|
+
const locale_1 = require("../locale");
|
|
5
|
+
const parser_1 = require("@atlisp/parser");
|
|
6
|
+
const BUILTIN_ARITY = {
|
|
7
|
+
// === Special forms & control flow ===
|
|
8
|
+
if: { min: 2, max: 3 },
|
|
9
|
+
progn: { min: 0, max: -1 },
|
|
10
|
+
cond: { min: 0, max: -1 },
|
|
11
|
+
while: { min: 1, max: -1 },
|
|
12
|
+
repeat: { min: 1, max: -1 },
|
|
13
|
+
foreach: { min: 2, max: -1 },
|
|
14
|
+
'vlax-for': { min: 2, max: -1 },
|
|
15
|
+
setq: { min: 2, max: -1 },
|
|
16
|
+
set: { min: 2, max: 2 },
|
|
17
|
+
lambda: { min: 1, max: -1 },
|
|
18
|
+
defun: { min: 3, max: -1 },
|
|
19
|
+
'defun-q': { min: 3, max: -1 },
|
|
20
|
+
and: { min: 0, max: -1 },
|
|
21
|
+
or: { min: 0, max: -1 },
|
|
22
|
+
not: { min: 1, max: 1 },
|
|
23
|
+
null: { min: 1, max: 1 },
|
|
24
|
+
quote: { min: 1, max: 1 },
|
|
25
|
+
function: { min: 1, max: 1 },
|
|
26
|
+
eval: { min: 1, max: 1 },
|
|
27
|
+
apply: { min: 2, max: -1 },
|
|
28
|
+
mapcar: { min: 2, max: -1 },
|
|
29
|
+
// === Predicates ===
|
|
30
|
+
atom: { min: 1, max: 1 },
|
|
31
|
+
boundp: { min: 1, max: 1 },
|
|
32
|
+
type: { min: 1, max: 1 },
|
|
33
|
+
numberp: { min: 1, max: 1 },
|
|
34
|
+
zerop: { min: 1, max: 1 },
|
|
35
|
+
minusp: { min: 1, max: 1 },
|
|
36
|
+
plusp: { min: 1, max: 1 },
|
|
37
|
+
eq: { min: 2, max: 2 },
|
|
38
|
+
equal: { min: 2, max: 2 },
|
|
39
|
+
'=': { min: 2, max: -1 },
|
|
40
|
+
'/=': { min: 2, max: -1 },
|
|
41
|
+
'<': { min: 2, max: -1 },
|
|
42
|
+
'<=': { min: 2, max: -1 },
|
|
43
|
+
'>': { min: 2, max: -1 },
|
|
44
|
+
'>=': { min: 2, max: -1 },
|
|
45
|
+
wcmatch: { min: 2, max: 2 },
|
|
46
|
+
member: { min: 2, max: 2 },
|
|
47
|
+
assoc: { min: 2, max: 3 },
|
|
48
|
+
// === List/cons operations ===
|
|
49
|
+
car: { min: 1, max: 1 },
|
|
50
|
+
cdr: { min: 1, max: 1 },
|
|
51
|
+
caar: { min: 1, max: 1 },
|
|
52
|
+
cadr: { min: 1, max: 1 },
|
|
53
|
+
cdar: { min: 1, max: 1 },
|
|
54
|
+
cddr: { min: 1, max: 1 },
|
|
55
|
+
caaar: { min: 1, max: 1 },
|
|
56
|
+
caadr: { min: 1, max: 1 },
|
|
57
|
+
cadar: { min: 1, max: 1 },
|
|
58
|
+
caddr: { min: 1, max: 1 },
|
|
59
|
+
cdaar: { min: 1, max: 1 },
|
|
60
|
+
cdadr: { min: 1, max: 1 },
|
|
61
|
+
cddar: { min: 1, max: 1 },
|
|
62
|
+
cdddr: { min: 1, max: 1 },
|
|
63
|
+
cons: { min: 2, max: 2 },
|
|
64
|
+
list: { min: 0, max: -1 },
|
|
65
|
+
append: { min: 0, max: -1 },
|
|
66
|
+
reverse: { min: 1, max: 1 },
|
|
67
|
+
length: { min: 1, max: 1 },
|
|
68
|
+
subst: { min: 3, max: 3 },
|
|
69
|
+
'vl-remove': { min: 2, max: 2 },
|
|
70
|
+
// === Arithmetic ===
|
|
71
|
+
'+': { min: 0, max: -1 },
|
|
72
|
+
'-': { min: 1, max: -1 },
|
|
73
|
+
'*': { min: 0, max: -1 },
|
|
74
|
+
'/': { min: 1, max: -1 },
|
|
75
|
+
'1+': { min: 1, max: 1 },
|
|
76
|
+
'1-': { min: 1, max: 1 },
|
|
77
|
+
abs: { min: 1, max: 1 },
|
|
78
|
+
fix: { min: 1, max: 1 },
|
|
79
|
+
float: { min: 1, max: 1 },
|
|
80
|
+
max: { min: 1, max: -1 },
|
|
81
|
+
min: { min: 1, max: -1 },
|
|
82
|
+
gcd: { min: 2, max: 2 },
|
|
83
|
+
rem: { min: 2, max: 2 },
|
|
84
|
+
logand: { min: 0, max: -1 },
|
|
85
|
+
logior: { min: 0, max: -1 },
|
|
86
|
+
logxor: { min: 0, max: -1 },
|
|
87
|
+
lsh: { min: 2, max: 2 },
|
|
88
|
+
boole: { min: 3, max: 3 },
|
|
89
|
+
exp: { min: 1, max: 1 },
|
|
90
|
+
expt: { min: 2, max: 2 },
|
|
91
|
+
log: { min: 1, max: 2 },
|
|
92
|
+
sqrt: { min: 1, max: 1 },
|
|
93
|
+
sin: { min: 1, max: 1 },
|
|
94
|
+
cos: { min: 1, max: 1 },
|
|
95
|
+
tan: { min: 1, max: 1 },
|
|
96
|
+
atan: { min: 1, max: 2 },
|
|
97
|
+
atof: { min: 1, max: 1 },
|
|
98
|
+
atoi: { min: 1, max: 1 },
|
|
99
|
+
itoa: { min: 1, max: 1 },
|
|
100
|
+
rtos: { min: 1, max: 3 },
|
|
101
|
+
distof: { min: 2, max: 2 },
|
|
102
|
+
cvunit: { min: 2, max: 2 },
|
|
103
|
+
// === String ===
|
|
104
|
+
strcat: { min: 0, max: -1 },
|
|
105
|
+
strlen: { min: 1, max: 1 },
|
|
106
|
+
substr: { min: 2, max: 3 },
|
|
107
|
+
strcase: { min: 1, max: 2 },
|
|
108
|
+
'vl-string->list': { min: 1, max: 1 },
|
|
109
|
+
'vl-string-search': { min: 2, max: 3 },
|
|
110
|
+
'vl-string-subst': { min: 3, max: 4 },
|
|
111
|
+
// === File I/O ===
|
|
112
|
+
open: { min: 2, max: 3 },
|
|
113
|
+
close: { min: 1, max: 1 },
|
|
114
|
+
'read-line': { min: 0, max: 1 },
|
|
115
|
+
'read-char': { min: 0, max: 1 },
|
|
116
|
+
'write-line': { min: 1, max: 2 },
|
|
117
|
+
'write-char': { min: 1, max: 2 },
|
|
118
|
+
'read': { min: 0, max: 1 },
|
|
119
|
+
princ: { min: 0, max: 2 },
|
|
120
|
+
prin1: { min: 0, max: 2 },
|
|
121
|
+
print: { min: 0, max: 2 },
|
|
122
|
+
terpri: { min: 0, max: 0 },
|
|
123
|
+
prompt: { min: 1, max: 1 },
|
|
124
|
+
getstring: { min: 0, max: 2 },
|
|
125
|
+
getint: { min: 0, max: 2 },
|
|
126
|
+
getreal: { min: 0, max: 2 },
|
|
127
|
+
getpoint: { min: 0, max: 3 },
|
|
128
|
+
getcorner: { min: 1, max: 3 },
|
|
129
|
+
getdist: { min: 0, max: 3 },
|
|
130
|
+
getangle: { min: 0, max: 3 },
|
|
131
|
+
getorient: { min: 0, max: 3 },
|
|
132
|
+
getkword: { min: 0, max: 2 },
|
|
133
|
+
initget: { min: 1, max: 2 },
|
|
134
|
+
'load': { min: 1, max: 2 },
|
|
135
|
+
autoload: { min: 2, max: 2 },
|
|
136
|
+
// === System ===
|
|
137
|
+
getvar: { min: 1, max: 1 },
|
|
138
|
+
setvar: { min: 2, max: 2 },
|
|
139
|
+
command: { min: 0, max: -1 },
|
|
140
|
+
'vl-cmdf': { min: 0, max: -1 },
|
|
141
|
+
gc: { min: 0, max: 0 },
|
|
142
|
+
ver: { min: 0, max: 0 },
|
|
143
|
+
exit: { min: 0, max: 0 },
|
|
144
|
+
quit: { min: 0, max: 0 },
|
|
145
|
+
findfile: { min: 1, max: 1 },
|
|
146
|
+
getfiled: { min: 3, max: 4 },
|
|
147
|
+
// === Entity/selection ===
|
|
148
|
+
entget: { min: 1, max: 2 },
|
|
149
|
+
entmod: { min: 1, max: 1 },
|
|
150
|
+
entmake: { min: 0, max: 1 },
|
|
151
|
+
entmakex: { min: 0, max: 1 },
|
|
152
|
+
entdel: { min: 1, max: 1 },
|
|
153
|
+
entsel: { min: 0, max: 2 },
|
|
154
|
+
nentsel: { min: 0, max: 2 },
|
|
155
|
+
entlast: { min: 0, max: 0 },
|
|
156
|
+
entnext: { min: 0, max: 1 },
|
|
157
|
+
handent: { min: 1, max: 1 },
|
|
158
|
+
entupd: { min: 1, max: 1 },
|
|
159
|
+
'ssget': { min: 0, max: -1 },
|
|
160
|
+
ssadd: { min: 0, max: 2 },
|
|
161
|
+
ssdel: { min: 2, max: 2 },
|
|
162
|
+
sslength: { min: 1, max: 1 },
|
|
163
|
+
ssname: { min: 2, max: 2 },
|
|
164
|
+
ssnamex: { min: 1, max: 2 },
|
|
165
|
+
sssetfirst: { min: 1, max: 2 },
|
|
166
|
+
// === Geometry ===
|
|
167
|
+
polar: { min: 3, max: 3 },
|
|
168
|
+
angle: { min: 2, max: 2 },
|
|
169
|
+
distance: { min: 2, max: 2 },
|
|
170
|
+
inters: { min: 4, max: 5 },
|
|
171
|
+
textbox: { min: 1, max: 1 },
|
|
172
|
+
trans: { min: 3, max: 4 },
|
|
173
|
+
// === Table/dictionary ===
|
|
174
|
+
tblobjname: { min: 2, max: 2 },
|
|
175
|
+
tblnext: { min: 2, max: 2 },
|
|
176
|
+
tblsearch: { min: 2, max: 3 },
|
|
177
|
+
acad_colordlg: { min: 1, max: 3 },
|
|
178
|
+
// === ActiveX ===
|
|
179
|
+
'vlax-invoke-method': { min: 2, max: -1 },
|
|
180
|
+
'vlax-get-property': { min: 2, max: 2 },
|
|
181
|
+
'vlax-put-property': { min: 3, max: 3 },
|
|
182
|
+
'vlax-get-or-create-object': { min: 1, max: 2 },
|
|
183
|
+
'vlax-create-object': { min: 1, max: 1 },
|
|
184
|
+
'vlax-get-object': { min: 1, max: 1 },
|
|
185
|
+
'vlax-release-object': { min: 1, max: 1 },
|
|
186
|
+
'vlax-safearray->list': { min: 1, max: 1 },
|
|
187
|
+
'vlax-safearray-fill': { min: 2, max: 2 },
|
|
188
|
+
'vlax-safearray-put-element': { min: 2, max: -1 },
|
|
189
|
+
'vlax-safearray-get-dim': { min: 1, max: 1 },
|
|
190
|
+
'vlax-safearray-get-element': { min: 2, max: -1 },
|
|
191
|
+
'vlax-make-safearray': { min: 2, max: 3 },
|
|
192
|
+
'vlax-ename->vla-object': { min: 1, max: 1 },
|
|
193
|
+
'vlax-vla-object->ename': { min: 1, max: 1 },
|
|
194
|
+
'vlax-tmatrix': { min: 1, max: 1 },
|
|
195
|
+
'vlax-curve-getarea': { min: 1, max: 1 },
|
|
196
|
+
'vlax-curve-getdistatparam': { min: 2, max: 2 },
|
|
197
|
+
'vlax-curve-getdistatpoint': { min: 2, max: 2 },
|
|
198
|
+
'vlax-curve-getendparam': { min: 1, max: 1 },
|
|
199
|
+
'vlax-curve-getendpoint': { min: 1, max: 1 },
|
|
200
|
+
'vlax-curve-getparamatdist': { min: 2, max: 2 },
|
|
201
|
+
'vlax-curve-getparamatpoint': { min: 2, max: 2 },
|
|
202
|
+
'vlax-curve-getpointatdist': { min: 2, max: 2 },
|
|
203
|
+
'vlax-curve-getpointatparam': { min: 2, max: 2 },
|
|
204
|
+
'vlax-curve-getstartparam': { min: 1, max: 1 },
|
|
205
|
+
'vlax-curve-getstartpoint': { min: 1, max: 1 },
|
|
206
|
+
'vlax-curve-isclosed': { min: 1, max: 1 },
|
|
207
|
+
'vlax-curve-getclosestpointto': { min: 2, max: 3 },
|
|
208
|
+
'vl-catch-all-apply': { min: 1, max: -1 },
|
|
209
|
+
'vl-catch-all-error-message': { min: 1, max: 1 },
|
|
210
|
+
'vlax-read-enabled-p': { min: 1, max: 1 },
|
|
211
|
+
'vlax-write-enabled-p': { min: 1, max: 1 },
|
|
212
|
+
'vlax-erased-p': { min: 1, max: 1 },
|
|
213
|
+
'vlax-object-released-p': { min: 1, max: 1 },
|
|
214
|
+
'vlax-ldata-get': { min: 2, max: 3 },
|
|
215
|
+
'vlax-ldata-put': { min: 3, max: 3 },
|
|
216
|
+
'vlax-ldata-delete': { min: 2, max: 3 },
|
|
217
|
+
'vlax-ldata-list': { min: 1, max: 2 },
|
|
218
|
+
'vlax-dump-object': { min: 1, max: 2 },
|
|
219
|
+
'vl-propagate': { min: 1, max: 1 },
|
|
220
|
+
'vl-exit-with-error': { min: 1, max: 1 },
|
|
221
|
+
'vl-exit-with-value': { min: 1, max: 1 },
|
|
222
|
+
'vl-position': { min: 2, max: 2 },
|
|
223
|
+
// === Symbol/function management ===
|
|
224
|
+
'atoms-family': { min: 1, max: 2 },
|
|
225
|
+
'vl-acad-defun': { min: 1, max: 1 },
|
|
226
|
+
'vl-acad-undefun': { min: 1, max: 1 },
|
|
227
|
+
'vl-symbol-name': { min: 1, max: 1 },
|
|
228
|
+
'vl-symbol-value': { min: 1, max: 1 },
|
|
229
|
+
'vl-bb-ref': { min: 1, max: 1 },
|
|
230
|
+
'vl-bb-set': { min: 2, max: 2 },
|
|
231
|
+
// === DOSLib / common plugins ===
|
|
232
|
+
dos_gettext: { min: 0, max: -1 },
|
|
233
|
+
// === Misc ===
|
|
234
|
+
trace: { min: 1, max: 1 },
|
|
235
|
+
untrace: { min: 1, max: 1 },
|
|
236
|
+
};
|
|
237
|
+
function checkBuiltinArgCount(content, file) {
|
|
238
|
+
const issues = [];
|
|
239
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
240
|
+
for (const node of (0, parser_1.astChildren)(ast)) {
|
|
241
|
+
checkNode(node, content, file, issues);
|
|
242
|
+
}
|
|
243
|
+
return issues;
|
|
244
|
+
}
|
|
245
|
+
function checkNode(node, content, file, issues) {
|
|
246
|
+
if (node.type !== 'list' || !node.children || node.children.length < 1)
|
|
247
|
+
return;
|
|
248
|
+
const head = node.children[0];
|
|
249
|
+
if (head.type !== 'symbol' || !head.name) {
|
|
250
|
+
for (const child of node.children) {
|
|
251
|
+
checkNode(child, content, file, issues);
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const funcName = head.name.toLowerCase();
|
|
256
|
+
const arity = BUILTIN_ARITY[funcName];
|
|
257
|
+
if (arity) {
|
|
258
|
+
const argCount = node.children.length - 1;
|
|
259
|
+
if (argCount < arity.min) {
|
|
260
|
+
issues.push({
|
|
261
|
+
file,
|
|
262
|
+
line: head.pos.line,
|
|
263
|
+
severity: 'warn',
|
|
264
|
+
rule: 'builtin_arg_count',
|
|
265
|
+
message: (0, locale_1.t)('builtin_arg_count.too_few', funcName, argCount, arity.min),
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
else if (arity.max !== -1 && argCount > arity.max) {
|
|
269
|
+
issues.push({
|
|
270
|
+
file,
|
|
271
|
+
line: head.pos.line,
|
|
272
|
+
severity: 'warn',
|
|
273
|
+
rule: 'builtin_arg_count',
|
|
274
|
+
message: (0, locale_1.t)('builtin_arg_count.too_many', funcName, argCount, arity.max),
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
for (const child of node.children) {
|
|
279
|
+
checkNode(child, content, file, issues);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=builtin-arg-count.js.map
|
|
@@ -18,7 +18,7 @@ function condKey(node) {
|
|
|
18
18
|
return '';
|
|
19
19
|
}
|
|
20
20
|
function checkCondDuplicate(content, file) {
|
|
21
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
21
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
22
22
|
return checkCondDuplicateAst(ast, file);
|
|
23
23
|
}
|
|
24
24
|
function checkCondDuplicateAst(ast, file) {
|
|
@@ -7,7 +7,7 @@ const parser_1 = require("@atlisp/parser");
|
|
|
7
7
|
const CONDITION_FORMS = new Set(['if', 'while']);
|
|
8
8
|
const CONSTANTS = new Set(['T', 'nil']);
|
|
9
9
|
function checkConstantCondition(content, file) {
|
|
10
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
10
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
11
11
|
return checkConstantConditionAst(ast, file);
|
|
12
12
|
}
|
|
13
13
|
function checkConstantConditionAst(ast, file) {
|
|
@@ -41,8 +41,8 @@ function checkConstantConditionAst(ast, file) {
|
|
|
41
41
|
continue;
|
|
42
42
|
const condTest = clause.children[0];
|
|
43
43
|
if (condTest.type === 'symbol' && condTest.name && CONSTANTS.has(condTest.name)) {
|
|
44
|
-
// Skip last clause with T
|
|
45
|
-
if (condTest.name === 'T' && i === condNode.children.length - 1)
|
|
44
|
+
// Skip last clause with T (only when there are multiple clauses — else/default pattern)
|
|
45
|
+
if (condTest.name === 'T' && i === condNode.children.length - 1 && i > 1)
|
|
46
46
|
continue;
|
|
47
47
|
issues.push({
|
|
48
48
|
file,
|
|
@@ -36,7 +36,7 @@ function isFunctionCall(list, name) {
|
|
|
36
36
|
return list.children[0].type === 'symbol' && list.children[0].name === name;
|
|
37
37
|
}
|
|
38
38
|
function checkDangerousCalls(content, file, config) {
|
|
39
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
39
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
40
40
|
return checkDangerousCallsAst(ast, file, config);
|
|
41
41
|
}
|
|
42
42
|
function checkDangerousCallsAst(ast, file, config) {
|
|
@@ -40,7 +40,7 @@ const fs = __importStar(require("fs"));
|
|
|
40
40
|
function checkDanglingDefun(file, allDefuns, allReferences) {
|
|
41
41
|
const issues = [];
|
|
42
42
|
const content = fs.readFileSync(file, 'utf-8');
|
|
43
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
43
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
44
44
|
const localDefuns = [];
|
|
45
45
|
const defunNodes = (0, parser_1.astFindAll)(ast, n => (0, parser_1.astIsList)(n, 'defun') || (0, parser_1.astIsList)(n, 'defun-q'));
|
|
46
46
|
for (const node of defunNodes) {
|
|
@@ -5,7 +5,7 @@ exports.checkDoubleNotAst = checkDoubleNotAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkDoubleNot(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkDoubleNotAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkDoubleNotAst(ast, file) {
|
|
@@ -7,7 +7,7 @@ const parser_1 = require("@atlisp/parser");
|
|
|
7
7
|
// AutoLISP only has `if` for conditional branching; `while` with no body is valid (no-op loop)
|
|
8
8
|
const BRANCH_FORMS = new Set(['if']);
|
|
9
9
|
function checkEmptyBranch(content, file) {
|
|
10
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
10
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
11
11
|
return checkEmptyBranchAst(ast, file);
|
|
12
12
|
}
|
|
13
13
|
function checkEmptyBranchAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ const locale_1 = require("../locale");
|
|
|
5
5
|
const parser_1 = require("@atlisp/parser");
|
|
6
6
|
function checkEmptyCatch(content, file) {
|
|
7
7
|
const issues = [];
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
const catchNodes = (0, parser_1.astFindAll)(ast, n => (0, parser_1.astIsList)(n, 'vl-catch-all-apply'));
|
|
10
10
|
for (const node of catchNodes) {
|
|
11
11
|
if (isInQuote(node))
|
|
@@ -5,7 +5,7 @@ exports.checkFunctionComplexityAst = checkFunctionComplexityAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkFunctionComplexity(content, file, maxLines, maxNesting) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkFunctionComplexityAst(ast, file, maxLines, maxNesting);
|
|
10
10
|
}
|
|
11
11
|
function checkFunctionComplexityAst(ast, file, maxLines, maxNesting) {
|
|
@@ -25,7 +25,7 @@ function isInsideLocalScope(node) {
|
|
|
25
25
|
}
|
|
26
26
|
function checkGlobalNaming(content, file) {
|
|
27
27
|
const issues = [];
|
|
28
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
28
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
29
29
|
const setqForms = (0, parser_1.astFindListWithHead)(ast, 'setq');
|
|
30
30
|
for (const form of setqForms) {
|
|
31
31
|
if (!form.children || form.children.length < 2)
|
|
@@ -27,7 +27,7 @@ function astEqual(a, b) {
|
|
|
27
27
|
return false;
|
|
28
28
|
}
|
|
29
29
|
function checkIdenticalBranches(content, file) {
|
|
30
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
30
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
31
31
|
return checkIdenticalBranchesAst(ast, file);
|
|
32
32
|
}
|
|
33
33
|
function checkIdenticalBranchesAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkMisplacedElseAst = checkMisplacedElseAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkMisplacedElse(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkMisplacedElseAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkMisplacedElseAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkMultipleSetqAst = checkMultipleSetqAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkMultipleSetq(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkMultipleSetqAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkMultipleSetqAst(ast, file) {
|
package/dist/checks/no-return.js
CHANGED
|
@@ -5,7 +5,7 @@ const locale_1 = require("../locale");
|
|
|
5
5
|
const parser_1 = require("@atlisp/parser");
|
|
6
6
|
function checkNoReturn(content, file) {
|
|
7
7
|
const issues = [];
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
const defuns = (0, parser_1.astFindListWithHead)(ast, 'defun');
|
|
10
10
|
for (const defun of defuns) {
|
|
11
11
|
if (!defun.children || defun.children.length < 3)
|
|
@@ -5,7 +5,7 @@ exports.checkOpenWithoutCloseAst = checkOpenWithoutCloseAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkOpenWithoutClose(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkOpenWithoutCloseAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkOpenWithoutCloseAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkParameterNamingAst = checkParameterNamingAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkParameterNaming(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkParameterNamingAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkParameterNamingAst(ast, file) {
|
|
@@ -17,7 +17,7 @@ const HIGHER_ORDER_FUNCS = new Set([
|
|
|
17
17
|
'vl-every',
|
|
18
18
|
]);
|
|
19
19
|
function checkQuoteVsFunction(content, file) {
|
|
20
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
20
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
21
21
|
return checkQuoteVsFunctionAst(ast, file);
|
|
22
22
|
}
|
|
23
23
|
function checkQuoteVsFunctionAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkRecursiveCallAst = checkRecursiveCallAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkRecursiveCall(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkRecursiveCallAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
/** Forms that provide conditional branching (exit condition for recursion) */
|
|
@@ -5,7 +5,7 @@ exports.checkRedundantLetAst = checkRedundantLetAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkRedundantLet(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkRedundantLetAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkRedundantLetAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkRedundantNilElseAst = checkRedundantNilElseAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkRedundantNilElse(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkRedundantNilElseAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkRedundantNilElseAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkRedundantPrognAst = checkRedundantPrognAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkRedundantProgn(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkRedundantPrognAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkRedundantPrognAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkRedundantQuotesAst = checkRedundantQuotesAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkRedundantQuotes(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkRedundantQuotesAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkRedundantQuotesAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkRedundantSetqAst = checkRedundantSetqAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkRedundantSetq(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkRedundantSetqAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkRedundantSetqAst(ast, file) {
|
|
@@ -6,7 +6,7 @@ const locale_1 = require("../locale");
|
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
const COMPARE_FUNCTIONS = new Set(['=', '/=', '<', '>', '<=', '>=', 'eq', 'equal']);
|
|
8
8
|
function checkSelfCompare(content, file) {
|
|
9
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
9
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
10
10
|
return checkSelfCompareAst(ast, file);
|
|
11
11
|
}
|
|
12
12
|
function checkSelfCompareAst(ast, file) {
|
|
@@ -5,7 +5,7 @@ exports.checkSetqSingleArgAst = checkSetqSingleArgAst;
|
|
|
5
5
|
const locale_1 = require("../locale");
|
|
6
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
7
|
function checkSetqSingleArg(content, file) {
|
|
8
|
-
const ast = (0, parser_1.parseAst)(content);
|
|
8
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
9
9
|
return checkSetqSingleArgAst(ast, file);
|
|
10
10
|
}
|
|
11
11
|
function checkSetqSingleArgAst(ast, file) {
|