@atlisp/lint 0.1.24 → 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.
@@ -57,7 +57,8 @@
57
57
  "error_handling": "warn",
58
58
  "global_naming": "warn",
59
59
  "extra_parens": "warn",
60
- "arg_count": "warn",
60
+ "arg_count": "error",
61
+ "builtin_arg_count": "error",
61
62
  "strcat_usage": "warn",
62
63
  "cond_simplify": "warn",
63
64
  "quote_style": "warn",
@@ -0,0 +1,3 @@
1
+ import { Issue } from '../types';
2
+ export declare function checkBuiltinArgCount(content: string, file: string): Issue[];
3
+ //# sourceMappingURL=builtin-arg-count.d.ts.map
@@ -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
package/dist/locale.js CHANGED
@@ -19,6 +19,8 @@ const messages = {
19
19
  token_in_url: 'Possible token exposure in string: token= in URL',
20
20
  open_without_close: 'File has {0} open() calls but {1} close() calls (possible resource leak)',
21
21
  arg_count: "Function '{0}' called with {1} arguments but defined with {2}",
22
+ 'builtin_arg_count.too_few': "Built-in function '{0}' called with {1} arguments, expected at least {2}",
23
+ 'builtin_arg_count.too_many': "Built-in function '{0}' called with {1} arguments, expected at most {2}",
22
24
  bare_function_names: "Unnamespaced function '{0}' (missing @:: or C: prefix)",
23
25
  module_registration: 'Module file missing @::*modules* registration (expected in last lines)',
24
26
  'namespace_header.missing': 'Missing (in-package {0}) header',
package/dist/rules.js CHANGED
@@ -11,7 +11,7 @@ exports.RULES = [
11
11
  },
12
12
  {
13
13
  name: 'arg_count',
14
- defaultSeverity: 'warn',
14
+ defaultSeverity: 'error',
15
15
  description: '检查函数调用参数数量是否与定义匹配',
16
16
  category: '最佳实践',
17
17
  },
@@ -236,6 +236,7 @@ exports.RULES = [
236
236
  { name: 'promise_handler', defaultSeverity: 'warn', description: '检测 vlax-invoke 缺少回调处理器', category: '最佳实践' },
237
237
  { name: 'module_cycle', defaultSeverity: 'warn', description: '检测模块循环依赖', category: '架构' },
238
238
  { name: 'arg_count_project', defaultSeverity: 'warn', description: '跨文件检查函数参数数量', category: '正确性' },
239
+ { name: 'builtin_arg_count', defaultSeverity: 'error', description: '检查 AutoLISP 内置函数调用参数个数是否匹配', category: '正确性' },
239
240
  ];
240
241
  function generateRulesMarkdown() {
241
242
  const lines = [
package/dist/runner.js CHANGED
@@ -59,6 +59,7 @@ const error_handling_1 = require("./checks/error-handling");
59
59
  const global_naming_1 = require("./checks/global-naming");
60
60
  const extra_parens_1 = require("./checks/extra-parens");
61
61
  const arg_count_1 = require("./checks/arg-count");
62
+ const builtin_arg_count_1 = require("./checks/builtin-arg-count");
62
63
  const strcat_usage_1 = require("./checks/strcat-usage");
63
64
  const cond_simplify_1 = require("./checks/cond-simplify");
64
65
  const quote_style_1 = require("./checks/quote-style");
@@ -137,6 +138,7 @@ function runChecks(content, file, config) {
137
138
  addIfEnabled('global_naming', () => (0, global_naming_1.checkGlobalNaming)(content, file));
138
139
  addIfEnabled('extra_parens', () => (0, extra_parens_1.checkExtraParens)(content, file));
139
140
  addIfEnabled('arg_count', () => (0, arg_count_1.checkArgCount)(content, file));
141
+ addIfEnabled('builtin_arg_count', () => (0, builtin_arg_count_1.checkBuiltinArgCount)(content, file));
140
142
  addIfEnabled('strcat_usage', () => (0, strcat_usage_1.checkStrcatUsage)(content, file));
141
143
  addIfEnabled('cond_simplify', () => (0, cond_simplify_1.checkCondSimplify)(content, file));
142
144
  addIfEnabled('quote_style', () => (0, quote_style_1.checkQuoteStyle)(content, file));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlisp/lint",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "description": "AutoLISP static analysis tool — parens, security, conventions, SBCL syntax validation",
5
5
  "keywords": [
6
6
  "CAD",