@atlisp/lint 0.2.11 → 0.2.13
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.schema.json +32 -2
- package/dist/cache.js +19 -9
- package/dist/checks/builtin-arg-count.d.ts +1 -0
- package/dist/checks/builtin-arg-count.js +5 -0
- package/dist/checks/dangerous-calls.js +1 -0
- package/dist/checks/dangling-defun.d.ts +7 -0
- package/dist/checks/dangling-defun.js +19 -0
- package/dist/checks/global-function-naming.js +159 -35
- package/dist/checks/missing-princ.js +2 -2
- package/dist/checks/nth-usage.d.ts +1 -0
- package/dist/checks/nth-usage.js +16 -1
- package/dist/checks/unused-package-dep.d.ts +1 -0
- package/dist/checks/unused-package-dep.js +53 -0
- package/dist/cli/collector.d.ts +7 -0
- package/dist/cli/collector.js +154 -0
- package/dist/cli/parser.d.ts +30 -0
- package/dist/cli/parser.js +119 -0
- package/dist/config.js +32 -6
- package/dist/disable.js +12 -0
- package/dist/fixes/index.d.ts +8 -0
- package/dist/fixes/index.js +200 -0
- package/dist/index.js +56 -236
- package/dist/locale.js +30 -2
- package/dist/presets.js +24 -0
- package/dist/project.js +182 -134
- package/dist/rules.d.ts +1 -0
- package/dist/rules.js +85 -0
- package/dist/runner.d.ts +2 -3
- package/dist/runner.js +46 -371
- package/dist/types.d.ts +6 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +43 -0
- package/dist/validate.js +12 -0
- package/dist/visitor-runner.d.ts +28 -0
- package/dist/visitor-runner.js +115 -1
- package/dist/visitors/equal-nil.d.ts +8 -0
- package/dist/visitors/equal-nil.js +26 -0
- package/dist/visitors/index.d.ts +5 -0
- package/dist/visitors/index.js +14 -0
- package/dist/visitors/progn-in-cond.d.ts +8 -0
- package/dist/visitors/progn-in-cond.js +33 -0
- package/dist/visitors/redundant-and-or.d.ts +8 -0
- package/dist/visitors/redundant-and-or.js +27 -0
- package/dist/visitors/redundant-car-cdr.d.ts +8 -0
- package/dist/visitors/redundant-car-cdr.js +35 -0
- package/dist/visitors/types.d.ts +13 -0
- package/dist/visitors/types.js +72 -0
- package/package.json +1 -1
package/atlisp-lint.schema.json
CHANGED
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"command_shell": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
52
52
|
"comment_style": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
53
53
|
"commented_code": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
54
|
+
"command_s": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
54
55
|
"cond_duplicate": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
55
56
|
"cond_simplify": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
56
57
|
"constant_condition": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
@@ -59,9 +60,11 @@
|
|
|
59
60
|
"duplicate_defun": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
60
61
|
"dynamic_doc": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
61
62
|
"empty_branch": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
63
|
+
"empty_branch_cond": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
62
64
|
"empty_catch": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
63
65
|
"empty_comment": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
64
66
|
"encoding": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
67
|
+
"equal_nil": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
65
68
|
"entget_in_loop": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
66
69
|
"eq_usage": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
67
70
|
"error_handling": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
@@ -69,9 +72,11 @@
|
|
|
69
72
|
"format_indent": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
70
73
|
"function_complexity": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
71
74
|
"function_order": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "off" },
|
|
75
|
+
"function_reference": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
72
76
|
"global_function_naming": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
73
77
|
"global_naming": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
74
78
|
"identical_branches": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
79
|
+
"if_progn_both": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
75
80
|
"if_without_else": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "off" },
|
|
76
81
|
"lambda_syntax": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "off" },
|
|
77
82
|
"line_length": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
@@ -92,11 +97,16 @@
|
|
|
92
97
|
"open_without_close": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
93
98
|
"parameter_naming": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
94
99
|
"parens": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
100
|
+
"progn_in_body": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
101
|
+
"progn_in_cond": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
95
102
|
"promise_handler": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "off" },
|
|
96
103
|
"quit_exit": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
97
104
|
"quote_style": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
98
105
|
"quote_vs_function": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
99
106
|
"recursive_call": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
107
|
+
"redundant_and_or": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
108
|
+
"redundant_car_cdr": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
109
|
+
"redundant_cond": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
100
110
|
"redundant_entmake": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
101
111
|
"redundant_if": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
102
112
|
"redundant_let": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
@@ -105,6 +115,7 @@
|
|
|
105
115
|
"redundant_progn": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
106
116
|
"redundant_quotes": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" },
|
|
107
117
|
"redundant_setq": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
118
|
+
"selection_set_leak": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
108
119
|
"self_compare": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
109
120
|
"setq_multiple": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
110
121
|
"setq_single_arg": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
@@ -127,7 +138,8 @@
|
|
|
127
138
|
"variable_shadow": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
128
139
|
"vl_registry_write": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
129
140
|
"vlax_without_loading": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "off" },
|
|
130
|
-
"while_constant": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" }
|
|
141
|
+
"while_constant": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
142
|
+
"zerop_usage": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "info" }
|
|
131
143
|
},
|
|
132
144
|
"additionalProperties": false
|
|
133
145
|
},
|
|
@@ -163,7 +175,8 @@
|
|
|
163
175
|
"exit": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "error" },
|
|
164
176
|
"command_shell": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
165
177
|
"startapp": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
166
|
-
"vl_registry_write": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" }
|
|
178
|
+
"vl_registry_write": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" },
|
|
179
|
+
"eval": { "type": "string", "enum": ["off", "info", "warn", "error"], "default": "warn" }
|
|
167
180
|
}
|
|
168
181
|
},
|
|
169
182
|
"module_registration": {
|
|
@@ -196,6 +209,23 @@
|
|
|
196
209
|
"walk_exclude": { "type": "array", "items": { "type": "string" }, "default": [".vscode", "vendor", ".git"] },
|
|
197
210
|
"defmacro_allow_files": { "type": "array", "items": { "type": "string" }, "default": ["compat-cl"] }
|
|
198
211
|
}
|
|
212
|
+
},
|
|
213
|
+
"project_analysis": {
|
|
214
|
+
"type": "object",
|
|
215
|
+
"properties": {
|
|
216
|
+
"maxFiles": {
|
|
217
|
+
"type": "integer",
|
|
218
|
+
"minimum": 1,
|
|
219
|
+
"default": 500,
|
|
220
|
+
"description": "Maximum number of files for cross-file analysis. Exceeding this threshold skips project analysis."
|
|
221
|
+
},
|
|
222
|
+
"batchSize": {
|
|
223
|
+
"type": "integer",
|
|
224
|
+
"minimum": 1,
|
|
225
|
+
"default": 50,
|
|
226
|
+
"description": "Files processed per batch (reserved for future streaming)"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
199
229
|
}
|
|
200
230
|
}
|
|
201
231
|
}
|
package/dist/cache.js
CHANGED
|
@@ -43,26 +43,36 @@ const CACHE_DIR = '.atlisp-lint-cache';
|
|
|
43
43
|
function getCacheDir(rootDir) {
|
|
44
44
|
return path.join(rootDir, CACHE_DIR);
|
|
45
45
|
}
|
|
46
|
-
function
|
|
47
|
-
return crypto.createHash('md5').update(content).digest('hex');
|
|
46
|
+
function contentKey(content) {
|
|
47
|
+
return 'hash-' + crypto.createHash('md5').update(content).digest('hex');
|
|
48
|
+
}
|
|
49
|
+
function statKey(filepath) {
|
|
50
|
+
try {
|
|
51
|
+
const stat = fs.statSync(filepath);
|
|
52
|
+
return `mtime-${stat.mtimeMs}-${stat.size}`;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
48
57
|
}
|
|
49
58
|
function isCached(filepath, rootDir, content) {
|
|
50
59
|
const cacheDir = getCacheDir(rootDir);
|
|
51
60
|
if (!fs.existsSync(cacheDir))
|
|
52
61
|
return false;
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return fs.existsSync(
|
|
62
|
+
const key = content !== undefined ? contentKey(content) : statKey(filepath);
|
|
63
|
+
if (!key)
|
|
64
|
+
return false;
|
|
65
|
+
return fs.existsSync(path.join(cacheDir, key));
|
|
57
66
|
}
|
|
58
67
|
function markCached(filepath, rootDir, content) {
|
|
59
68
|
const cacheDir = getCacheDir(rootDir);
|
|
60
69
|
if (!fs.existsSync(cacheDir)) {
|
|
61
70
|
fs.mkdirSync(cacheDir, { recursive: true });
|
|
62
71
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
const key = content !== undefined ? contentKey(content) : statKey(filepath);
|
|
73
|
+
if (!key)
|
|
74
|
+
return;
|
|
75
|
+
const cacheFile = path.join(cacheDir, key);
|
|
66
76
|
fs.writeFileSync(cacheFile, '');
|
|
67
77
|
}
|
|
68
78
|
function clearCache(rootDir) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BUILTIN_FUNCTIONS = void 0;
|
|
3
4
|
exports.checkBuiltinArgCount = checkBuiltinArgCount;
|
|
4
5
|
const locale_1 = require("../locale");
|
|
5
6
|
const parser_1 = require("@atlisp/parser");
|
|
7
|
+
exports.BUILTIN_FUNCTIONS = new Set();
|
|
6
8
|
const BUILTIN_ARITY = {
|
|
7
9
|
// === Special forms & control flow ===
|
|
8
10
|
if: { min: 2, max: 3 },
|
|
@@ -234,6 +236,9 @@ const BUILTIN_ARITY = {
|
|
|
234
236
|
trace: { min: 1, max: 1 },
|
|
235
237
|
untrace: { min: 1, max: 1 },
|
|
236
238
|
};
|
|
239
|
+
for (const key of Object.keys(BUILTIN_ARITY)) {
|
|
240
|
+
exports.BUILTIN_FUNCTIONS.add(key);
|
|
241
|
+
}
|
|
237
242
|
function checkBuiltinArgCount(content, file) {
|
|
238
243
|
const issues = [];
|
|
239
244
|
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
@@ -15,6 +15,7 @@ const PATTERNS = [
|
|
|
15
15
|
functionCall: true,
|
|
16
16
|
},
|
|
17
17
|
{ rule: 'command_shell', key: 'command_shell', messageKey: 'dangerous.command_shell', commandShell: true },
|
|
18
|
+
{ rule: 'eval', key: 'eval', messageKey: 'dangerous.eval', functionCall: true },
|
|
18
19
|
];
|
|
19
20
|
function isInQuote(node) {
|
|
20
21
|
let cur = node.parent;
|
|
@@ -6,4 +6,11 @@ export declare function checkDanglingDefun(file: string, allDefuns: Map<string,
|
|
|
6
6
|
file: string;
|
|
7
7
|
line: number;
|
|
8
8
|
}[]>): Issue[];
|
|
9
|
+
export declare function checkDanglingDefunFromDefs(localDefuns: {
|
|
10
|
+
name: string;
|
|
11
|
+
line: number;
|
|
12
|
+
}[], allReferences: Map<string, {
|
|
13
|
+
file: string;
|
|
14
|
+
line: number;
|
|
15
|
+
}[]>, file: string): Issue[];
|
|
9
16
|
//# sourceMappingURL=dangling-defun.d.ts.map
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.checkDanglingDefun = checkDanglingDefun;
|
|
37
|
+
exports.checkDanglingDefunFromDefs = checkDanglingDefunFromDefs;
|
|
37
38
|
const locale_1 = require("../locale");
|
|
38
39
|
const parser_1 = require("@atlisp/parser");
|
|
39
40
|
const fs = __importStar(require("fs"));
|
|
@@ -64,4 +65,22 @@ function checkDanglingDefun(file, allDefuns, allReferences) {
|
|
|
64
65
|
}
|
|
65
66
|
return issues;
|
|
66
67
|
}
|
|
68
|
+
function checkDanglingDefunFromDefs(localDefuns, allReferences, file) {
|
|
69
|
+
const issues = [];
|
|
70
|
+
for (const defun of localDefuns) {
|
|
71
|
+
const refs = allReferences.get(defun.name) || [];
|
|
72
|
+
const calledElsewhere = refs.some(r => r.file !== file);
|
|
73
|
+
const calledLocally = refs.some(r => r.file === file);
|
|
74
|
+
if (!calledLocally && !calledElsewhere) {
|
|
75
|
+
issues.push({
|
|
76
|
+
file,
|
|
77
|
+
line: defun.line,
|
|
78
|
+
severity: 'warn',
|
|
79
|
+
rule: 'dangling_defun',
|
|
80
|
+
message: (0, locale_1.t)('dangling_defun', defun.name),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return issues;
|
|
85
|
+
}
|
|
67
86
|
//# sourceMappingURL=dangling-defun.js.map
|
|
@@ -4,41 +4,165 @@ exports.checkGlobalFunctionNaming = checkGlobalFunctionNaming;
|
|
|
4
4
|
const locale_1 = require("../locale");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
const BUILTIN_FUNCTIONS = new Set([
|
|
7
|
-
'if',
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'
|
|
7
|
+
'if',
|
|
8
|
+
'cond',
|
|
9
|
+
'when',
|
|
10
|
+
'unless',
|
|
11
|
+
'progn',
|
|
12
|
+
'setq',
|
|
13
|
+
'setq-e',
|
|
14
|
+
'while',
|
|
15
|
+
'repeat',
|
|
16
|
+
'foreach',
|
|
17
|
+
'lambda',
|
|
18
|
+
'function',
|
|
19
|
+
'quote',
|
|
20
|
+
'defun',
|
|
21
|
+
'defun-q',
|
|
22
|
+
'defmacro',
|
|
23
|
+
'let',
|
|
24
|
+
'let*',
|
|
25
|
+
'mapcar',
|
|
26
|
+
'apply',
|
|
27
|
+
'eval',
|
|
28
|
+
'load',
|
|
29
|
+
'require',
|
|
30
|
+
'car',
|
|
31
|
+
'cdr',
|
|
32
|
+
'cadr',
|
|
33
|
+
'cdar',
|
|
34
|
+
'caar',
|
|
35
|
+
'cddr',
|
|
36
|
+
'caddr',
|
|
37
|
+
'cadar',
|
|
38
|
+
'cons',
|
|
39
|
+
'list',
|
|
40
|
+
'append',
|
|
41
|
+
'reverse',
|
|
42
|
+
'nth',
|
|
43
|
+
'assoc',
|
|
44
|
+
'subst',
|
|
45
|
+
'member',
|
|
46
|
+
'length',
|
|
47
|
+
'numberp',
|
|
48
|
+
'stringp',
|
|
49
|
+
'listp',
|
|
50
|
+
'atom',
|
|
51
|
+
'null',
|
|
52
|
+
'not',
|
|
53
|
+
'eq',
|
|
54
|
+
'equal',
|
|
55
|
+
'=',
|
|
56
|
+
'/=',
|
|
57
|
+
'<',
|
|
58
|
+
'>',
|
|
59
|
+
'<=',
|
|
60
|
+
'>=',
|
|
61
|
+
'+',
|
|
62
|
+
'-',
|
|
63
|
+
'*',
|
|
64
|
+
'/',
|
|
65
|
+
'1+',
|
|
66
|
+
'1-',
|
|
67
|
+
'abs',
|
|
68
|
+
'min',
|
|
69
|
+
'max',
|
|
70
|
+
'strcat',
|
|
71
|
+
'substr',
|
|
72
|
+
'strlen',
|
|
73
|
+
'strcase',
|
|
74
|
+
'itoa',
|
|
75
|
+
'atoi',
|
|
76
|
+
'rtos',
|
|
77
|
+
'atof',
|
|
78
|
+
'fix',
|
|
79
|
+
'float',
|
|
80
|
+
'princ',
|
|
81
|
+
'print',
|
|
82
|
+
'prin1',
|
|
83
|
+
'prompt',
|
|
84
|
+
'terpri',
|
|
85
|
+
'open',
|
|
86
|
+
'close',
|
|
87
|
+
'read-line',
|
|
88
|
+
'write-line',
|
|
89
|
+
'read-char',
|
|
90
|
+
'write-char',
|
|
91
|
+
'entmake',
|
|
92
|
+
'entmakex',
|
|
93
|
+
'entget',
|
|
94
|
+
'entmod',
|
|
95
|
+
'entdel',
|
|
96
|
+
'entlast',
|
|
97
|
+
'entnext',
|
|
98
|
+
'ssget',
|
|
99
|
+
'ssadd',
|
|
100
|
+
'ssdel',
|
|
101
|
+
'sslength',
|
|
102
|
+
'ssname',
|
|
103
|
+
'ssmemb',
|
|
104
|
+
'command',
|
|
105
|
+
'vl-cmdf',
|
|
106
|
+
'vlax-invoke',
|
|
107
|
+
'vlax-invoke-method',
|
|
108
|
+
'vlax-get',
|
|
109
|
+
'vlax-put',
|
|
110
|
+
'vlax-get-property',
|
|
111
|
+
'vlax-put-property',
|
|
112
|
+
'vlax-make-variant',
|
|
113
|
+
'vlax-variant-value',
|
|
114
|
+
'vlax-safearray',
|
|
115
|
+
'vlax-safearray-fill',
|
|
116
|
+
'vlax-safearray->list',
|
|
117
|
+
'vl-catch-all-apply',
|
|
118
|
+
'vl-catch-all-error-p',
|
|
119
|
+
'vl-catch-all-error-message',
|
|
120
|
+
'vl-load-com',
|
|
121
|
+
'vlax-dump-object',
|
|
122
|
+
'vlax-for',
|
|
123
|
+
'vl-registry-read',
|
|
124
|
+
'vl-registry-write',
|
|
125
|
+
'vl-registry-delete',
|
|
126
|
+
'vl-file-copy',
|
|
127
|
+
'vl-file-delete',
|
|
128
|
+
'vl-file-rename',
|
|
129
|
+
'vl-directory-files',
|
|
130
|
+
'vl-mkdir',
|
|
131
|
+
'vl-string->list',
|
|
132
|
+
'vl-list->string',
|
|
133
|
+
'vl-string-search',
|
|
134
|
+
'vl-string-subst',
|
|
135
|
+
'vl-string-position',
|
|
136
|
+
'vl-string-mismatch',
|
|
137
|
+
'vl-symbol-value',
|
|
138
|
+
'vl-symbol-name',
|
|
139
|
+
'vl-sort',
|
|
140
|
+
'vl-sort-i',
|
|
141
|
+
'vl-remove-if',
|
|
142
|
+
'vl-remove-if-not',
|
|
143
|
+
'vl-member-if',
|
|
144
|
+
'vl-some',
|
|
145
|
+
'vl-every',
|
|
146
|
+
'vl-position',
|
|
147
|
+
'vl-consp',
|
|
148
|
+
'startapp',
|
|
149
|
+
'quit',
|
|
150
|
+
'exit',
|
|
151
|
+
'*error*',
|
|
152
|
+
'vla-get-',
|
|
153
|
+
'vla-put-',
|
|
154
|
+
'vlax-ename->vla-object',
|
|
155
|
+
'vlax-vla-object->ename',
|
|
156
|
+
'vlax-3d-point',
|
|
157
|
+
'vlax-tmatrix',
|
|
158
|
+
'vlax-curve-getarea',
|
|
159
|
+
'vlax-curve-getdistatparam',
|
|
160
|
+
'vlax-curve-getparamatdist',
|
|
161
|
+
'vlax-curve-getclosestpointto',
|
|
162
|
+
'vlax-curve-getstartpoint',
|
|
163
|
+
'vlax-curve-getendpoint',
|
|
164
|
+
'vlax-curve-getpointatdist',
|
|
165
|
+
'vlax-curve-getpointatparam',
|
|
42
166
|
]);
|
|
43
167
|
function checkGlobalFunctionNaming(content, file) {
|
|
44
168
|
const issues = [];
|
|
@@ -26,11 +26,11 @@ function checkMissingPrinc(content, file) {
|
|
|
26
26
|
if (body.length === 0)
|
|
27
27
|
continue;
|
|
28
28
|
const lastForm = body[body.length - 1];
|
|
29
|
-
const isPrincCall =
|
|
29
|
+
const isPrincCall = lastForm.type === 'list' &&
|
|
30
30
|
lastForm.children &&
|
|
31
31
|
lastForm.children.length > 0 &&
|
|
32
32
|
(0, parser_1.astIsSymbol)(lastForm.children[0]) &&
|
|
33
|
-
['princ', 'print', 'prin1'].includes(lastForm.children[0].name || '')
|
|
33
|
+
['princ', 'print', 'prin1'].includes(lastForm.children[0].name || '');
|
|
34
34
|
if (!isPrincCall) {
|
|
35
35
|
issues.push({
|
|
36
36
|
file,
|
package/dist/checks/nth-usage.js
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.checkNthUsage = checkNthUsage;
|
|
4
|
+
exports.replaceNthUsage = replaceNthUsage;
|
|
4
5
|
const locale_1 = require("../locale");
|
|
5
6
|
const utils_1 = require("../utils");
|
|
7
|
+
const NTH_RE = /\(nth\s+(\d+)\b/;
|
|
8
|
+
const REPLACEMENTS = {
|
|
9
|
+
'0': 'car',
|
|
10
|
+
'1': 'cadr',
|
|
11
|
+
'2': 'caddr',
|
|
12
|
+
'3': 'cadddr',
|
|
13
|
+
};
|
|
6
14
|
function checkNthUsage(content, file) {
|
|
7
15
|
const issues = [];
|
|
8
16
|
const lines = content.split('\n');
|
|
9
17
|
for (let i = 0; i < lines.length; i++) {
|
|
10
18
|
const stripped = (0, utils_1.stripLine)(lines[i]);
|
|
11
|
-
|
|
19
|
+
const m = stripped.match(NTH_RE);
|
|
20
|
+
if (m && REPLACEMENTS[m[1]]) {
|
|
12
21
|
issues.push({ file, line: i + 1, severity: 'warn', rule: 'nth_usage', message: (0, locale_1.t)('nth_usage') });
|
|
13
22
|
}
|
|
14
23
|
}
|
|
15
24
|
return issues;
|
|
16
25
|
}
|
|
26
|
+
function replaceNthUsage(line) {
|
|
27
|
+
return line.replace(NTH_RE, (_, idx) => {
|
|
28
|
+
const replacement = REPLACEMENTS[idx];
|
|
29
|
+
return replacement ? `(${replacement} ` : `(nth ${idx} `;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
17
32
|
//# sourceMappingURL=nth-usage.js.map
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.checkUnusedPackageDep = checkUnusedPackageDep;
|
|
37
|
+
exports.checkUnusedPackageDepFromContent = checkUnusedPackageDepFromContent;
|
|
37
38
|
const locale_1 = require("../locale");
|
|
38
39
|
const parser_1 = require("@atlisp/parser");
|
|
39
40
|
const fs = __importStar(require("fs"));
|
|
@@ -90,4 +91,56 @@ function checkUnusedPackageDep(file) {
|
|
|
90
91
|
}
|
|
91
92
|
return issues;
|
|
92
93
|
}
|
|
94
|
+
function checkUnusedPackageDepFromContent(file, content) {
|
|
95
|
+
const issues = [];
|
|
96
|
+
const ast = (0, parser_1.parseAst)(content, { errorRecovery: true });
|
|
97
|
+
const inPackageNodes = (0, parser_1.astFindAll)(ast, n => (0, parser_1.astIsList)(n, 'in-package'));
|
|
98
|
+
if (inPackageNodes.length === 0)
|
|
99
|
+
return issues;
|
|
100
|
+
const allPackages = new Set();
|
|
101
|
+
for (const node of inPackageNodes) {
|
|
102
|
+
if (node.children && node.children.length >= 2 && (0, parser_1.astIsSymbol)(node.children[1])) {
|
|
103
|
+
allPackages.add(node.children[1].name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const usedSymbols = new Set();
|
|
107
|
+
const allLists = (0, parser_1.astFindAll)(ast, n => n.type === 'list');
|
|
108
|
+
for (const node of allLists) {
|
|
109
|
+
if (!node.children || node.children.length === 0)
|
|
110
|
+
continue;
|
|
111
|
+
const car = node.children[0];
|
|
112
|
+
if (car.type === 'symbol' && car.name) {
|
|
113
|
+
const parts = car.name.split(':');
|
|
114
|
+
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
115
|
+
usedSymbols.add(parts[0]);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for (let i = 1; i < node.children.length; i++) {
|
|
119
|
+
const child = node.children[i];
|
|
120
|
+
if (child.type === 'symbol' && child.name) {
|
|
121
|
+
const parts = child.name.split(':');
|
|
122
|
+
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
123
|
+
usedSymbols.add(parts[0]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const mainPackage = inPackageNodes.length > 0 && inPackageNodes[0].children && inPackageNodes[0].children[1]
|
|
129
|
+
? inPackageNodes[0].children[1].name || ''
|
|
130
|
+
: '';
|
|
131
|
+
allPackages.delete(mainPackage);
|
|
132
|
+
for (const pkg of allPackages) {
|
|
133
|
+
if (!usedSymbols.has(pkg)) {
|
|
134
|
+
const node = inPackageNodes.find(n => n.children && n.children.length >= 2 && (0, parser_1.astIsSymbol)(n.children[1]) && n.children[1].name === pkg);
|
|
135
|
+
issues.push({
|
|
136
|
+
file,
|
|
137
|
+
line: node ? node.pos.line : 1,
|
|
138
|
+
severity: 'warn',
|
|
139
|
+
rule: 'unused_package_dep',
|
|
140
|
+
message: (0, locale_1.t)('unused_package_dep', pkg),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return issues;
|
|
145
|
+
}
|
|
93
146
|
//# sourceMappingURL=unused-package-dep.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LintConfig } from '../types';
|
|
2
|
+
import { CliOptions } from './parser';
|
|
3
|
+
declare function collectChangedFiles(rootDir: string, baseBranch: string): string[];
|
|
4
|
+
export declare function collectFiles(rootDir: string, opts: CliOptions, config: LintConfig): string[];
|
|
5
|
+
export declare function collectStagedFiles(rootDir: string): string[];
|
|
6
|
+
export { collectChangedFiles };
|
|
7
|
+
//# sourceMappingURL=collector.d.ts.map
|