@atlisp/lint 0.1.2 → 0.1.4
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 +3 -0
- package/atlisp-lint.default.json +26 -7
- package/dist/checks/bare-names.js +4 -1
- package/dist/checks/cl-syntax.js +4 -1
- package/dist/checks/commented-code.d.ts +3 -0
- package/dist/checks/commented-code.js +46 -0
- package/dist/checks/constant-condition.d.ts +5 -0
- package/dist/checks/constant-condition.js +88 -0
- package/dist/checks/dangerous-calls.d.ts +2 -0
- package/dist/checks/dangerous-calls.js +70 -29
- package/dist/checks/dangling-defun.d.ts +6 -0
- package/dist/checks/dangling-defun.js +85 -0
- package/dist/checks/double-not.d.ts +5 -0
- package/dist/checks/double-not.js +30 -0
- package/dist/checks/empty-branch.d.ts +5 -0
- package/dist/checks/empty-branch.js +34 -0
- package/dist/checks/empty-comments.d.ts +3 -0
- package/dist/checks/empty-comments.js +26 -0
- package/dist/checks/encoding.js +13 -4
- package/dist/checks/function-complexity.d.ts +2 -0
- package/dist/checks/function-complexity.js +89 -45
- package/dist/checks/line-length.js +4 -1
- package/dist/checks/misplaced-else.d.ts +5 -0
- package/dist/checks/misplaced-else.js +31 -0
- package/dist/checks/missing-doc.js +5 -2
- package/dist/checks/missing-export.d.ts +13 -0
- package/dist/checks/missing-export.js +94 -0
- package/dist/checks/module-reg.js +9 -4
- package/dist/checks/multiple-setq.d.ts +5 -0
- package/dist/checks/multiple-setq.js +51 -0
- package/dist/checks/namespace-header.js +16 -6
- package/dist/checks/open-close.d.ts +2 -0
- package/dist/checks/open-close.js +18 -13
- package/dist/checks/parameter-naming.d.ts +2 -0
- package/dist/checks/parameter-naming.js +26 -14
- package/dist/checks/parens.js +8 -3
- package/dist/checks/quote-vs-function.d.ts +5 -0
- package/dist/checks/quote-vs-function.js +50 -0
- package/dist/checks/recursive-call.d.ts +5 -0
- package/dist/checks/recursive-call.js +49 -0
- package/dist/checks/redundant-cond.d.ts +5 -0
- package/dist/checks/redundant-cond.js +50 -0
- package/dist/checks/redundant-let.d.ts +5 -0
- package/dist/checks/redundant-let.js +31 -0
- package/dist/checks/redundant-nil-else.d.ts +5 -0
- package/dist/checks/redundant-nil-else.js +32 -0
- package/dist/checks/redundant-progn.d.ts +5 -0
- package/dist/checks/redundant-progn.js +31 -0
- package/dist/checks/redundant-quotes.d.ts +5 -0
- package/dist/checks/redundant-quotes.js +33 -0
- package/dist/checks/redundant-setq.d.ts +5 -0
- package/dist/checks/redundant-setq.js +34 -0
- package/dist/checks/self-compare.d.ts +5 -0
- package/dist/checks/self-compare.js +37 -0
- package/dist/checks/single-arg-and-or.d.ts +5 -0
- package/dist/checks/single-arg-and-or.js +32 -0
- package/dist/checks/token-in-url.js +4 -1
- package/dist/checks/trailing-paren.d.ts +3 -0
- package/dist/checks/trailing-paren.js +44 -0
- package/dist/checks/trailing-ws.js +4 -1
- package/dist/checks/unused-let.d.ts +5 -0
- package/dist/checks/unused-let.js +57 -0
- package/dist/checks/unused-local-fun.d.ts +5 -0
- package/dist/checks/unused-local-fun.js +62 -0
- package/dist/checks/unused-package-dep.d.ts +3 -0
- package/dist/checks/unused-package-dep.js +93 -0
- package/dist/checks/unused-param.d.ts +5 -0
- package/dist/checks/unused-param.js +63 -0
- package/dist/checks/unused-variable.d.ts +2 -0
- package/dist/checks/unused-variable.js +70 -30
- package/dist/checks/variable-shadow.d.ts +5 -0
- package/dist/checks/variable-shadow.js +66 -0
- package/dist/checks/vlax.js +8 -3
- package/dist/config.d.ts +1 -2
- package/dist/config.js +0 -13
- package/dist/disable.js +4 -1
- package/dist/formatters.d.ts +1 -2
- package/dist/formatters.js +8 -61
- package/dist/index.d.ts +1 -1
- package/dist/index.js +137 -117
- package/dist/locale.js +83 -47
- package/dist/project.d.ts +3 -0
- package/dist/project.js +138 -0
- package/dist/runner.d.ts +3 -0
- package/dist/runner.js +215 -23
- package/dist/sbcl.js +16 -11
- package/dist/worker.js +10 -50
- package/lib/lint-sbcl.lisp +19 -54
- package/package.json +18 -4
- package/dist/atlisp-lint.default.json +0 -71
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js.map +0 -1
- package/dist/checks/arg-count.d.ts +0 -3
- package/dist/checks/arg-count.d.ts.map +0 -1
- package/dist/checks/arg-count.js +0 -120
- package/dist/checks/arg-count.js.map +0 -1
- package/dist/checks/bare-names.d.ts.map +0 -1
- package/dist/checks/bare-names.js.map +0 -1
- package/dist/checks/cl-syntax.d.ts.map +0 -1
- package/dist/checks/cl-syntax.js.map +0 -1
- package/dist/checks/cond-simplify.d.ts +0 -3
- package/dist/checks/cond-simplify.d.ts.map +0 -1
- package/dist/checks/cond-simplify.js +0 -42
- package/dist/checks/cond-simplify.js.map +0 -1
- package/dist/checks/dangerous-calls.d.ts.map +0 -1
- package/dist/checks/dangerous-calls.js.map +0 -1
- package/dist/checks/encoding.d.ts.map +0 -1
- package/dist/checks/encoding.js.map +0 -1
- package/dist/checks/error-handling.d.ts +0 -3
- package/dist/checks/error-handling.d.ts.map +0 -1
- package/dist/checks/error-handling.js +0 -53
- package/dist/checks/error-handling.js.map +0 -1
- package/dist/checks/extra-parens.d.ts +0 -3
- package/dist/checks/extra-parens.d.ts.map +0 -1
- package/dist/checks/extra-parens.js +0 -42
- package/dist/checks/extra-parens.js.map +0 -1
- package/dist/checks/function-complexity.d.ts.map +0 -1
- package/dist/checks/function-complexity.js.map +0 -1
- package/dist/checks/global-naming.d.ts +0 -3
- package/dist/checks/global-naming.d.ts.map +0 -1
- package/dist/checks/global-naming.js +0 -51
- package/dist/checks/global-naming.js.map +0 -1
- package/dist/checks/line-length.d.ts.map +0 -1
- package/dist/checks/line-length.js.map +0 -1
- package/dist/checks/missing-doc.d.ts.map +0 -1
- package/dist/checks/missing-doc.js.map +0 -1
- package/dist/checks/module-reg.d.ts.map +0 -1
- package/dist/checks/module-reg.js.map +0 -1
- package/dist/checks/namespace-header.d.ts.map +0 -1
- package/dist/checks/namespace-header.js.map +0 -1
- package/dist/checks/open-close.d.ts.map +0 -1
- package/dist/checks/open-close.js.map +0 -1
- package/dist/checks/parameter-naming.d.ts.map +0 -1
- package/dist/checks/parameter-naming.js.map +0 -1
- package/dist/checks/parens.d.ts.map +0 -1
- package/dist/checks/parens.js.map +0 -1
- package/dist/checks/strcat-usage.d.ts +0 -3
- package/dist/checks/strcat-usage.d.ts.map +0 -1
- package/dist/checks/strcat-usage.js +0 -22
- package/dist/checks/strcat-usage.js.map +0 -1
- package/dist/checks/token-in-url.d.ts.map +0 -1
- package/dist/checks/token-in-url.js.map +0 -1
- package/dist/checks/trailing-ws.d.ts.map +0 -1
- package/dist/checks/trailing-ws.js.map +0 -1
- package/dist/checks/unused-variable.d.ts.map +0 -1
- package/dist/checks/unused-variable.js.map +0 -1
- package/dist/checks/vlax.d.ts.map +0 -1
- package/dist/checks/vlax.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/disable.d.ts.map +0 -1
- package/dist/disable.js.map +0 -1
- package/dist/formatters.d.ts.map +0 -1
- package/dist/formatters.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/lint-sbcl.lisp +0 -161
- package/dist/locale.d.ts.map +0 -1
- package/dist/locale.js.map +0 -1
- package/dist/rules.d.ts +0 -9
- package/dist/rules.d.ts.map +0 -1
- package/dist/rules.js +0 -39
- package/dist/rules.js.map +0 -1
- package/dist/runner.d.ts.map +0 -1
- package/dist/runner.js.map +0 -1
- package/dist/sbcl.d.ts.map +0 -1
- package/dist/sbcl.js.map +0 -1
- package/dist/stub-packages.json +0 -41
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js.map +0 -1
- package/dist/validate.d.ts +0 -8
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -55
- package/dist/validate.js.map +0 -1
- package/dist/watch.d.ts +0 -9
- package/dist/watch.d.ts.map +0 -1
- package/dist/watch.js +0 -109
- package/dist/watch.js.map +0 -1
- package/dist/worker.d.ts.map +0 -1
- package/dist/worker.js.map +0 -1
- package/pre-commit/hook.sh +0 -4
package/dist/runner.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Issue, LintConfig } from './types';
|
|
2
|
+
export declare function runChecks(content: string, file: string, config: LintConfig): Issue[];
|
|
3
|
+
/** Single-pass visitor-based runChecks using AstVisitor */
|
|
4
|
+
export declare function runChecksWithVisitor(content: string, file: string, config: LintConfig): Issue[];
|
|
2
5
|
export declare function lintFiles(files: string[], config: LintConfig, rootDir: string): Issue[];
|
|
3
6
|
export declare function lintFilesParallel(files: string[], config: LintConfig, rootDir: string): Promise<Issue[]>;
|
|
4
7
|
export declare function fixFile(filepath: string): string[];
|
package/dist/runner.js
CHANGED
|
@@ -33,6 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runChecks = runChecks;
|
|
37
|
+
exports.runChecksWithVisitor = runChecksWithVisitor;
|
|
36
38
|
exports.lintFiles = lintFiles;
|
|
37
39
|
exports.lintFilesParallel = lintFilesParallel;
|
|
38
40
|
exports.fixFile = fixFile;
|
|
@@ -56,19 +58,41 @@ const function_complexity_1 = require("./checks/function-complexity");
|
|
|
56
58
|
const parameter_naming_1 = require("./checks/parameter-naming");
|
|
57
59
|
const unused_variable_1 = require("./checks/unused-variable");
|
|
58
60
|
const missing_doc_1 = require("./checks/missing-doc");
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
61
|
+
const unused_param_1 = require("./checks/unused-param");
|
|
62
|
+
const constant_condition_1 = require("./checks/constant-condition");
|
|
63
|
+
const redundant_progn_1 = require("./checks/redundant-progn");
|
|
64
|
+
const empty_branch_1 = require("./checks/empty-branch");
|
|
65
|
+
const unused_let_1 = require("./checks/unused-let");
|
|
66
|
+
const recursive_call_1 = require("./checks/recursive-call");
|
|
67
|
+
const variable_shadow_1 = require("./checks/variable-shadow");
|
|
68
|
+
const redundant_cond_1 = require("./checks/redundant-cond");
|
|
69
|
+
const unused_local_fun_1 = require("./checks/unused-local-fun");
|
|
70
|
+
const multiple_setq_1 = require("./checks/multiple-setq");
|
|
71
|
+
const redundant_quotes_1 = require("./checks/redundant-quotes");
|
|
72
|
+
const trailing_paren_1 = require("./checks/trailing-paren");
|
|
73
|
+
const empty_comments_1 = require("./checks/empty-comments");
|
|
74
|
+
const redundant_setq_1 = require("./checks/redundant-setq");
|
|
75
|
+
const redundant_nil_else_1 = require("./checks/redundant-nil-else");
|
|
76
|
+
const single_arg_and_or_1 = require("./checks/single-arg-and-or");
|
|
77
|
+
const redundant_let_1 = require("./checks/redundant-let");
|
|
78
|
+
const self_compare_1 = require("./checks/self-compare");
|
|
79
|
+
const misplaced_else_1 = require("./checks/misplaced-else");
|
|
80
|
+
const quote_vs_function_1 = require("./checks/quote-vs-function");
|
|
81
|
+
const commented_code_1 = require("./checks/commented-code");
|
|
82
|
+
const double_not_1 = require("./checks/double-not");
|
|
65
83
|
const config_1 = require("./config");
|
|
66
84
|
const locale_1 = require("./locale");
|
|
67
85
|
const disable_1 = require("./disable");
|
|
86
|
+
const parser_1 = require("@atlisp/parser");
|
|
68
87
|
function runChecks(content, file, config) {
|
|
69
88
|
const issues = [];
|
|
70
89
|
const disableMap = (0, disable_1.parseDisableComments)(content);
|
|
90
|
+
// Parse AST once for all checks that need it
|
|
91
|
+
const ast = (0, parser_1.parseAst)(content);
|
|
71
92
|
function addIfEnabled(rule, fn) {
|
|
93
|
+
const severity = config.checks[rule];
|
|
94
|
+
if (severity === 'off')
|
|
95
|
+
return;
|
|
72
96
|
const results = fn();
|
|
73
97
|
for (const r of results) {
|
|
74
98
|
if (!(0, disable_1.isDisabled)(r.rule, r.line, disableMap)) {
|
|
@@ -79,25 +103,131 @@ function runChecks(content, file, config) {
|
|
|
79
103
|
addIfEnabled('encoding', () => (0, encoding_1.checkEncoding)(content, file));
|
|
80
104
|
addIfEnabled('parens', () => (0, parens_1.checkParens)(content, file));
|
|
81
105
|
addIfEnabled('cl_syntax', () => (0, cl_syntax_1.checkClSyntax)(content, file, config.cl_syntax.keywords));
|
|
82
|
-
addIfEnabled('quit_exit', () => (0, dangerous_calls_1.
|
|
106
|
+
addIfEnabled('quit_exit', () => (0, dangerous_calls_1.checkDangerousCallsAst)(ast, file, config.dangerous_calls));
|
|
83
107
|
addIfEnabled('vlax_without_loading', () => (0, vlax_1.checkVlaxWithoutLoading)(content, file));
|
|
84
108
|
addIfEnabled('token_in_url', () => (0, token_in_url_1.checkTokenInUrl)(content, file));
|
|
85
|
-
addIfEnabled('open_without_close', () => (0, open_close_1.
|
|
109
|
+
addIfEnabled('open_without_close', () => (0, open_close_1.checkOpenWithoutCloseAst)(ast, file));
|
|
86
110
|
addIfEnabled('bare_function_names', () => (0, bare_names_1.checkBareFunctionNames)(content, file, config.bare_function_names.allowlist, config.bare_function_names.namespace_pattern));
|
|
87
111
|
addIfEnabled('module_registration', () => (0, module_reg_1.checkModuleRegistration)(content, file, file, config.module_registration));
|
|
88
112
|
addIfEnabled('namespace_header', () => (0, namespace_header_1.checkNamespaceHeader)(content, file, config.namespace_header));
|
|
89
113
|
addIfEnabled('line_length', () => (0, line_length_1.checkLineLength)(content, file, config.line_length.max, config.line_length.tab_width));
|
|
90
|
-
addIfEnabled('function_complexity', () => (0, function_complexity_1.
|
|
91
|
-
addIfEnabled('parameter_naming', () => (0, parameter_naming_1.
|
|
92
|
-
addIfEnabled('unused_variable', () => (0, unused_variable_1.
|
|
114
|
+
addIfEnabled('function_complexity', () => (0, function_complexity_1.checkFunctionComplexityAst)(ast, file, config.function_complexity.max_lines, config.function_complexity.max_nesting));
|
|
115
|
+
addIfEnabled('parameter_naming', () => (0, parameter_naming_1.checkParameterNamingAst)(ast, file));
|
|
116
|
+
addIfEnabled('unused_variable', () => (0, unused_variable_1.checkUnusedVariableAst)(ast, file));
|
|
93
117
|
addIfEnabled('missing_doc', () => (0, missing_doc_1.checkMissingDoc)(content, file));
|
|
94
|
-
addIfEnabled('error_handling', () => (0, error_handling_1.checkErrorHandling)(content, file));
|
|
95
|
-
addIfEnabled('global_naming', () => (0, global_naming_1.checkGlobalNaming)(content, file));
|
|
96
|
-
addIfEnabled('extra_parens', () => (0, extra_parens_1.checkExtraParens)(content, file));
|
|
97
|
-
addIfEnabled('arg_count', () => (0, arg_count_1.checkArgCount)(content, file));
|
|
98
|
-
addIfEnabled('strcat_usage', () => (0, strcat_usage_1.checkStrcatUsage)(content, file));
|
|
99
|
-
addIfEnabled('cond_simplify', () => (0, cond_simplify_1.checkCondSimplify)(content, file));
|
|
100
118
|
addIfEnabled('trailing_whitespace', () => (0, trailing_ws_1.checkTrailingWhitespace)(content, file));
|
|
119
|
+
addIfEnabled('unused_parameter', () => (0, unused_param_1.checkUnusedParameterAst)(ast, file));
|
|
120
|
+
addIfEnabled('constant_condition', () => (0, constant_condition_1.checkConstantConditionAst)(ast, file));
|
|
121
|
+
addIfEnabled('redundant_progn', () => (0, redundant_progn_1.checkRedundantPrognAst)(ast, file));
|
|
122
|
+
addIfEnabled('empty_branch', () => (0, empty_branch_1.checkEmptyBranchAst)(ast, file));
|
|
123
|
+
addIfEnabled('unused_let_binding', () => (0, unused_let_1.checkUnusedLetBindingAst)(ast, file));
|
|
124
|
+
addIfEnabled('recursive_call', () => (0, recursive_call_1.checkRecursiveCallAst)(ast, file));
|
|
125
|
+
addIfEnabled('variable_shadow', () => (0, variable_shadow_1.checkVariableShadowAst)(ast, file));
|
|
126
|
+
addIfEnabled('redundant_cond', () => (0, redundant_cond_1.checkRedundantCondAst)(ast, file));
|
|
127
|
+
addIfEnabled('unused_local_fun', () => (0, unused_local_fun_1.checkUnusedLocalFunAst)(ast, file));
|
|
128
|
+
addIfEnabled('multiple_setq', () => (0, multiple_setq_1.checkMultipleSetqAst)(ast, file));
|
|
129
|
+
addIfEnabled('redundant_quotes', () => (0, redundant_quotes_1.checkRedundantQuotesAst)(ast, file));
|
|
130
|
+
addIfEnabled('trailing_paren', () => (0, trailing_paren_1.checkTrailingParen)(content, file));
|
|
131
|
+
addIfEnabled('empty_comment', () => (0, empty_comments_1.checkEmptyComments)(content, file));
|
|
132
|
+
addIfEnabled('redundant_setq', () => (0, redundant_setq_1.checkRedundantSetqAst)(ast, file));
|
|
133
|
+
addIfEnabled('redundant_nil_else', () => (0, redundant_nil_else_1.checkRedundantNilElseAst)(ast, file));
|
|
134
|
+
addIfEnabled('single_arg_and_or', () => (0, single_arg_and_or_1.checkSingleArgAndOrAst)(ast, file));
|
|
135
|
+
addIfEnabled('redundant_let', () => (0, redundant_let_1.checkRedundantLetAst)(ast, file));
|
|
136
|
+
addIfEnabled('self_compare', () => (0, self_compare_1.checkSelfCompareAst)(ast, file));
|
|
137
|
+
addIfEnabled('misplaced_else', () => (0, misplaced_else_1.checkMisplacedElseAst)(ast, file));
|
|
138
|
+
addIfEnabled('quote_vs_function', () => (0, quote_vs_function_1.checkQuoteVsFunctionAst)(ast, file));
|
|
139
|
+
addIfEnabled('commented_code', () => (0, commented_code_1.checkCommentedCode)(content, file));
|
|
140
|
+
addIfEnabled('double_not', () => (0, double_not_1.checkDoubleNotAst)(ast, file));
|
|
141
|
+
return issues;
|
|
142
|
+
}
|
|
143
|
+
/** Single-pass visitor-based runChecks using AstVisitor */
|
|
144
|
+
function runChecksWithVisitor(content, file, config) {
|
|
145
|
+
const issues = [];
|
|
146
|
+
const disableMap = (0, disable_1.parseDisableComments)(content);
|
|
147
|
+
const ast = (0, parser_1.parseAst)(content);
|
|
148
|
+
const visitor = new parser_1.AstVisitor();
|
|
149
|
+
const checks = config.checks;
|
|
150
|
+
function addIssue(rule, line, severity, message) {
|
|
151
|
+
if (severity === 'off')
|
|
152
|
+
return;
|
|
153
|
+
if (!(0, disable_1.isDisabled)(rule, line, disableMap)) {
|
|
154
|
+
issues.push({ file, line, severity: severity, rule, message });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Register all AST-based checks as visitor handlers
|
|
158
|
+
if (checks['redundant_quotes'] !== 'off') {
|
|
159
|
+
visitor.on('quote', (node) => {
|
|
160
|
+
if (node.children &&
|
|
161
|
+
node.children.length >= 2 &&
|
|
162
|
+
node.children[1].type === 'list' &&
|
|
163
|
+
node.children[1].children &&
|
|
164
|
+
node.children[1].children.length > 0 &&
|
|
165
|
+
node.children[1].children[0].type === 'symbol' &&
|
|
166
|
+
node.children[1].children[0].name === 'quote') {
|
|
167
|
+
addIssue('redundant_quotes', node.pos.line, checks['redundant_quotes'], (0, locale_1.t)('redundant_quotes'));
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (checks['double_not'] !== 'off') {
|
|
172
|
+
visitor.on('not', (node) => {
|
|
173
|
+
if (node.children &&
|
|
174
|
+
node.children.length >= 2 &&
|
|
175
|
+
node.children[1].type === 'list' &&
|
|
176
|
+
node.children[1].children &&
|
|
177
|
+
node.children[1].children.length > 0 &&
|
|
178
|
+
node.children[1].children[0].type === 'symbol' &&
|
|
179
|
+
node.children[1].children[0].name === 'not') {
|
|
180
|
+
addIssue('double_not', node.pos.line, checks['double_not'], (0, locale_1.t)('double_not'));
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (checks['misplaced_else'] !== 'off') {
|
|
185
|
+
visitor.on('if', (node) => {
|
|
186
|
+
if (node.children && node.children.length === 4) {
|
|
187
|
+
const cond = node.children[1];
|
|
188
|
+
if (cond.type === 'list' &&
|
|
189
|
+
cond.children &&
|
|
190
|
+
cond.children.length >= 2 &&
|
|
191
|
+
cond.children[0].type === 'symbol' &&
|
|
192
|
+
cond.children[0].name === 'not') {
|
|
193
|
+
const innerName = cond.children[1].name || '';
|
|
194
|
+
addIssue('misplaced_else', node.pos.line, checks['misplaced_else'], (0, locale_1.t)('misplaced_else', innerName));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (checks['quote_vs_function'] !== 'off') {
|
|
200
|
+
const higherOrder = new Set([
|
|
201
|
+
'mapcar',
|
|
202
|
+
'apply',
|
|
203
|
+
'lambda',
|
|
204
|
+
'vl-sort',
|
|
205
|
+
'vl-sort-i',
|
|
206
|
+
'vl-remove-if',
|
|
207
|
+
'vl-remove-if-not',
|
|
208
|
+
'vl-member-if',
|
|
209
|
+
'vl-some',
|
|
210
|
+
'vl-every',
|
|
211
|
+
]);
|
|
212
|
+
visitor.on('quote', (node) => {
|
|
213
|
+
if (node.children &&
|
|
214
|
+
node.children.length >= 2 &&
|
|
215
|
+
node.children[1].type === 'list' &&
|
|
216
|
+
node.children[1].children &&
|
|
217
|
+
node.children[1].children.length > 0 &&
|
|
218
|
+
node.children[1].children[0].type === 'symbol' &&
|
|
219
|
+
node.children[1].children[0].name === 'lambda') {
|
|
220
|
+
const parent = node.parent;
|
|
221
|
+
if (parent && parent.children && parent.children.length > 0) {
|
|
222
|
+
const pName = (parent.children[0].type === 'symbol' && parent.children[0].name) || '';
|
|
223
|
+
if (higherOrder.has(pName)) {
|
|
224
|
+
addIssue('quote_vs_function', node.pos.line, checks['quote_vs_function'], (0, locale_1.t)('quote_vs_function', pName));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
visitor.run(ast);
|
|
101
231
|
return issues;
|
|
102
232
|
}
|
|
103
233
|
function lintFiles(files, config, rootDir) {
|
|
@@ -111,7 +241,10 @@ function lintFiles(files, config, rootDir) {
|
|
|
111
241
|
}
|
|
112
242
|
catch {
|
|
113
243
|
allIssues.push({
|
|
114
|
-
file: relPath,
|
|
244
|
+
file: relPath,
|
|
245
|
+
line: 1,
|
|
246
|
+
severity: 'error',
|
|
247
|
+
rule: 'read',
|
|
115
248
|
message: (0, locale_1.t)('runner.read_error'),
|
|
116
249
|
});
|
|
117
250
|
continue;
|
|
@@ -125,7 +258,7 @@ function lintFiles(files, config, rootDir) {
|
|
|
125
258
|
}
|
|
126
259
|
function lintFilesParallel(files, config, rootDir) {
|
|
127
260
|
(0, locale_1.setLocale)(config.locale || 'zh');
|
|
128
|
-
return new Promise((resolve
|
|
261
|
+
return new Promise((resolve) => {
|
|
129
262
|
const allIssues = [];
|
|
130
263
|
let completed = 0;
|
|
131
264
|
const maxWorkers = Math.min(os.cpus().length, files.length);
|
|
@@ -138,7 +271,6 @@ function lintFilesParallel(files, config, rootDir) {
|
|
|
138
271
|
const relPath = path.relative(rootDir, filepath);
|
|
139
272
|
const worker = new worker_threads_1.Worker(path.join(__dirname, 'worker.js'), {
|
|
140
273
|
workerData: { filepath, relPath, config },
|
|
141
|
-
eval: false,
|
|
142
274
|
});
|
|
143
275
|
worker.on('message', (msg) => {
|
|
144
276
|
allIssues.push(...msg.issues);
|
|
@@ -150,7 +282,10 @@ function lintFilesParallel(files, config, rootDir) {
|
|
|
150
282
|
});
|
|
151
283
|
worker.on('error', (err) => {
|
|
152
284
|
allIssues.push({
|
|
153
|
-
file: relPath,
|
|
285
|
+
file: relPath,
|
|
286
|
+
line: 1,
|
|
287
|
+
severity: 'error',
|
|
288
|
+
rule: 'worker',
|
|
154
289
|
message: err.message,
|
|
155
290
|
});
|
|
156
291
|
completed++;
|
|
@@ -159,6 +294,21 @@ function lintFilesParallel(files, config, rootDir) {
|
|
|
159
294
|
if (completed >= files.length)
|
|
160
295
|
resolve(allIssues);
|
|
161
296
|
});
|
|
297
|
+
worker.on('exit', (code) => {
|
|
298
|
+
if (code !== 0) {
|
|
299
|
+
allIssues.push({
|
|
300
|
+
file: relPath,
|
|
301
|
+
line: 1,
|
|
302
|
+
severity: 'error',
|
|
303
|
+
rule: 'worker',
|
|
304
|
+
message: `Worker exited with code ${code}`,
|
|
305
|
+
});
|
|
306
|
+
completed++;
|
|
307
|
+
startWorker();
|
|
308
|
+
if (completed >= files.length)
|
|
309
|
+
resolve(allIssues);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
162
312
|
}
|
|
163
313
|
for (let i = 0; i < maxWorkers; i++) {
|
|
164
314
|
startWorker();
|
|
@@ -167,20 +317,62 @@ function lintFilesParallel(files, config, rootDir) {
|
|
|
167
317
|
resolve([]);
|
|
168
318
|
});
|
|
169
319
|
}
|
|
320
|
+
const UTF8_BOM = 0xfeff;
|
|
170
321
|
function fixFile(filepath) {
|
|
171
322
|
const fixes = [];
|
|
172
323
|
let content = fs.readFileSync(filepath, 'utf-8');
|
|
173
324
|
// Fix trailing whitespace
|
|
174
|
-
const wsFixed = content
|
|
325
|
+
const wsFixed = content
|
|
326
|
+
.split('\n')
|
|
327
|
+
.map((l) => l.replace(/[ \t]+$/, ''))
|
|
328
|
+
.join('\n');
|
|
175
329
|
if (wsFixed !== content) {
|
|
176
330
|
content = wsFixed;
|
|
177
331
|
fixes.push('trailing_whitespace');
|
|
178
332
|
}
|
|
179
333
|
// Fix UTF-8 BOM
|
|
180
|
-
if (content.charCodeAt(0) ===
|
|
334
|
+
if (content.charCodeAt(0) === UTF8_BOM) {
|
|
181
335
|
content = content.slice(1);
|
|
182
336
|
fixes.push('encoding (BOM)');
|
|
183
337
|
}
|
|
338
|
+
// Fix trailing parens: remove excess ')' from end of content
|
|
339
|
+
let openCount = 0;
|
|
340
|
+
let closeCount = 0;
|
|
341
|
+
let fixContent = content;
|
|
342
|
+
for (let i = 0; i < fixContent.length; i++) {
|
|
343
|
+
const ch = fixContent[i];
|
|
344
|
+
if (ch === '(')
|
|
345
|
+
openCount++;
|
|
346
|
+
else if (ch === ')')
|
|
347
|
+
closeCount++;
|
|
348
|
+
}
|
|
349
|
+
if (closeCount > openCount) {
|
|
350
|
+
let excess = closeCount - openCount;
|
|
351
|
+
while (excess > 0 && fixContent.endsWith(')')) {
|
|
352
|
+
fixContent = fixContent.slice(0, -1);
|
|
353
|
+
excess--;
|
|
354
|
+
}
|
|
355
|
+
// Also trim trailing whitespace after removing parens
|
|
356
|
+
fixContent = fixContent.replace(/\n[ \t]*$/, '');
|
|
357
|
+
if (fixContent !== content) {
|
|
358
|
+
content = fixContent;
|
|
359
|
+
fixes.push('trailing_paren');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Fix empty comments: remove lines that are only ';' with optional whitespace
|
|
363
|
+
const lines = content.split('\n');
|
|
364
|
+
let changed = false;
|
|
365
|
+
const fixedLines = lines.map((l) => {
|
|
366
|
+
if (/^\s*;\s*$/.test(l)) {
|
|
367
|
+
changed = true;
|
|
368
|
+
return '';
|
|
369
|
+
}
|
|
370
|
+
return l;
|
|
371
|
+
});
|
|
372
|
+
if (changed) {
|
|
373
|
+
content = fixedLines.join('\n');
|
|
374
|
+
fixes.push('empty_comment');
|
|
375
|
+
}
|
|
184
376
|
if (fixes.length > 0) {
|
|
185
377
|
fs.writeFileSync(filepath, content, 'utf-8');
|
|
186
378
|
}
|
package/dist/sbcl.js
CHANGED
|
@@ -60,22 +60,26 @@ function runSbclLint(srcDir, sbclConfig, stubPackagesPath) {
|
|
|
60
60
|
// Locate lint-sbcl.lisp bundled with the package
|
|
61
61
|
const scriptPath = path.join(__dirname, '..', 'lib', 'lint-sbcl.lisp');
|
|
62
62
|
if (!fs.existsSync(scriptPath)) {
|
|
63
|
-
return [
|
|
64
|
-
|
|
63
|
+
return [
|
|
64
|
+
{
|
|
65
|
+
file: 'internal',
|
|
66
|
+
line: 1,
|
|
67
|
+
severity: 'error',
|
|
68
|
+
rule: 'sbcl',
|
|
65
69
|
message: (0, locale_1.t)('sbcl.script_not_found', scriptPath),
|
|
66
|
-
}
|
|
70
|
+
},
|
|
71
|
+
];
|
|
67
72
|
}
|
|
68
73
|
try {
|
|
69
74
|
// Convert arrays to Lisp-readable format: ("a" "b")
|
|
70
|
-
const toLispList = (arr) => '(' + arr.map(s => `"${s}"`).join(' ') + ')';
|
|
71
|
-
const locale = (0, locale_1.getLocale)();
|
|
75
|
+
const toLispList = (arr) => '(' + arr.map((s) => `"${s}"`).join(' ') + ')';
|
|
72
76
|
const result = (0, child_process_1.execFileSync)(sbcl, [
|
|
73
|
-
'--script',
|
|
77
|
+
'--script',
|
|
78
|
+
scriptPath,
|
|
74
79
|
srcDir,
|
|
75
80
|
stubPackagesPath,
|
|
76
81
|
toLispList(sbclConfig.walk_exclude),
|
|
77
82
|
toLispList(sbclConfig.defmacro_allow_files),
|
|
78
|
-
locale,
|
|
79
83
|
], {
|
|
80
84
|
encoding: 'utf-8',
|
|
81
85
|
maxBuffer: 50 * 1024 * 1024,
|
|
@@ -111,9 +115,7 @@ function parseSbclOutput(output, srcDir) {
|
|
|
111
115
|
const severity = sev === 'ERROR' ? 'error' : 'warn';
|
|
112
116
|
const lineno = lineStr ? parseInt(lineStr, 10) : 1;
|
|
113
117
|
// Resolve relative path against srcDir
|
|
114
|
-
const resolved = filePath.includes(':')
|
|
115
|
-
? filePath
|
|
116
|
-
: filePath.replace(/\\/g, '/');
|
|
118
|
+
const resolved = filePath.includes(':') ? filePath : filePath.replace(/\\/g, '/');
|
|
117
119
|
issues.push({
|
|
118
120
|
file: resolved,
|
|
119
121
|
line: lineno,
|
|
@@ -128,7 +130,10 @@ function parseSbclOutput(output, srcDir) {
|
|
|
128
130
|
if (sev) {
|
|
129
131
|
const msg = trimmed.replace(/^\[(ERROR|WARN|NOTE)\]\s*/, '');
|
|
130
132
|
issues.push({
|
|
131
|
-
file: srcDir,
|
|
133
|
+
file: srcDir,
|
|
134
|
+
line: 1,
|
|
135
|
+
severity: sev,
|
|
136
|
+
rule: 'sbcl',
|
|
132
137
|
message: msg,
|
|
133
138
|
});
|
|
134
139
|
}
|
package/dist/worker.js
CHANGED
|
@@ -3,68 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const worker_threads_1 = require("worker_threads");
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const locale_1 = require("./locale");
|
|
6
|
-
const
|
|
7
|
-
const encoding_1 = require("./checks/encoding");
|
|
8
|
-
const parens_1 = require("./checks/parens");
|
|
9
|
-
const cl_syntax_1 = require("./checks/cl-syntax");
|
|
10
|
-
const dangerous_calls_1 = require("./checks/dangerous-calls");
|
|
11
|
-
const vlax_1 = require("./checks/vlax");
|
|
12
|
-
const token_in_url_1 = require("./checks/token-in-url");
|
|
13
|
-
const open_close_1 = require("./checks/open-close");
|
|
14
|
-
const bare_names_1 = require("./checks/bare-names");
|
|
15
|
-
const module_reg_1 = require("./checks/module-reg");
|
|
16
|
-
const namespace_header_1 = require("./checks/namespace-header");
|
|
17
|
-
const line_length_1 = require("./checks/line-length");
|
|
18
|
-
const function_complexity_1 = require("./checks/function-complexity");
|
|
19
|
-
const parameter_naming_1 = require("./checks/parameter-naming");
|
|
20
|
-
const unused_variable_1 = require("./checks/unused-variable");
|
|
21
|
-
const missing_doc_1 = require("./checks/missing-doc");
|
|
22
|
-
const trailing_ws_1 = require("./checks/trailing-ws");
|
|
23
|
-
function runChecks(content, file, config) {
|
|
24
|
-
const issues = [];
|
|
25
|
-
const disableMap = (0, disable_1.parseDisableComments)(content);
|
|
26
|
-
function addIfEnabled(rule, fn) {
|
|
27
|
-
const results = fn();
|
|
28
|
-
for (const r of results) {
|
|
29
|
-
if (!(0, disable_1.isDisabled)(r.rule, r.line, disableMap)) {
|
|
30
|
-
issues.push(r);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
addIfEnabled('encoding', () => (0, encoding_1.checkEncoding)(content, file));
|
|
35
|
-
addIfEnabled('parens', () => (0, parens_1.checkParens)(content, file));
|
|
36
|
-
addIfEnabled('cl_syntax', () => (0, cl_syntax_1.checkClSyntax)(content, file, config.cl_syntax.keywords));
|
|
37
|
-
addIfEnabled('quit_exit', () => (0, dangerous_calls_1.checkDangerousCalls)(content, file, config.dangerous_calls));
|
|
38
|
-
addIfEnabled('vlax_without_loading', () => (0, vlax_1.checkVlaxWithoutLoading)(content, file));
|
|
39
|
-
addIfEnabled('token_in_url', () => (0, token_in_url_1.checkTokenInUrl)(content, file));
|
|
40
|
-
addIfEnabled('open_without_close', () => (0, open_close_1.checkOpenWithoutClose)(content, file));
|
|
41
|
-
addIfEnabled('bare_function_names', () => (0, bare_names_1.checkBareFunctionNames)(content, file, config.bare_function_names.allowlist, config.bare_function_names.namespace_pattern));
|
|
42
|
-
addIfEnabled('module_registration', () => (0, module_reg_1.checkModuleRegistration)(content, file, file, config.module_registration));
|
|
43
|
-
addIfEnabled('namespace_header', () => (0, namespace_header_1.checkNamespaceHeader)(content, file, config.namespace_header));
|
|
44
|
-
addIfEnabled('line_length', () => (0, line_length_1.checkLineLength)(content, file, config.line_length.max, config.line_length.tab_width));
|
|
45
|
-
addIfEnabled('function_complexity', () => (0, function_complexity_1.checkFunctionComplexity)(content, file, config.function_complexity.max_lines, config.function_complexity.max_nesting));
|
|
46
|
-
addIfEnabled('parameter_naming', () => (0, parameter_naming_1.checkParameterNaming)(content, file));
|
|
47
|
-
addIfEnabled('unused_variable', () => (0, unused_variable_1.checkUnusedVariable)(content, file));
|
|
48
|
-
addIfEnabled('missing_doc', () => (0, missing_doc_1.checkMissingDoc)(content, file));
|
|
49
|
-
addIfEnabled('trailing_whitespace', () => (0, trailing_ws_1.checkTrailingWhitespace)(content, file));
|
|
50
|
-
return issues;
|
|
51
|
-
}
|
|
6
|
+
const runner_1 = require("./runner");
|
|
52
7
|
if (worker_threads_1.parentPort && worker_threads_1.workerData) {
|
|
53
8
|
const input = worker_threads_1.workerData;
|
|
54
9
|
(0, locale_1.setLocale)(input.config.locale || 'zh');
|
|
55
10
|
try {
|
|
56
11
|
const content = (0, fs_1.readFileSync)(input.filepath, 'utf-8');
|
|
57
|
-
const issues = runChecks(content, input.relPath, input.config);
|
|
12
|
+
const issues = (0, runner_1.runChecks)(content, input.relPath, input.config);
|
|
58
13
|
const output = { filepath: input.filepath, issues };
|
|
59
14
|
worker_threads_1.parentPort.postMessage(output);
|
|
60
15
|
}
|
|
61
16
|
catch {
|
|
62
17
|
const output = {
|
|
63
18
|
filepath: input.filepath,
|
|
64
|
-
issues: [
|
|
65
|
-
|
|
19
|
+
issues: [
|
|
20
|
+
{
|
|
21
|
+
file: input.relPath,
|
|
22
|
+
line: 1,
|
|
23
|
+
severity: 'error',
|
|
24
|
+
rule: 'read',
|
|
66
25
|
message: 'Cannot read file',
|
|
67
|
-
}
|
|
26
|
+
},
|
|
27
|
+
],
|
|
68
28
|
};
|
|
69
29
|
worker_threads_1.parentPort.postMessage(output);
|
|
70
30
|
}
|
package/lib/lint-sbcl.lisp
CHANGED
|
@@ -1,49 +1,14 @@
|
|
|
1
1
|
;; @lisp SBCL Lint — syntax validation via SBCL
|
|
2
|
-
;; Usage: sbcl --script lint-sbcl.lisp <src-dir> <stub-packages.json> <walk-exclude-json> <defmacro-allow-files-json>
|
|
2
|
+
;; Usage: sbcl --script lint-sbcl.lisp <src-dir> <stub-packages.json> <walk-exclude-json> <defmacro-allow-files-json>
|
|
3
3
|
|
|
4
4
|
(require :uiop)
|
|
5
5
|
|
|
6
6
|
(defparameter *errors* 0)
|
|
7
7
|
(defparameter *warnings* 0)
|
|
8
8
|
(defparameter *checked* 0)
|
|
9
|
-
(defparameter *locale* "zh")
|
|
10
|
-
|
|
11
|
-
;; ── i18n ──────────────────────────────────────────────────────────────
|
|
12
|
-
(defun i18n (key)
|
|
13
|
-
(cdr (assoc key
|
|
14
|
-
(if (string= *locale* "zh")
|
|
15
|
-
'((:not-found . "not found symbol")
|
|
16
|
-
(:syntax-error . "syntax error")
|
|
17
|
-
(:vec-syntax . "#( vector syntax")
|
|
18
|
-
(:char-syntax . "# backslash char literal")
|
|
19
|
-
(:eval-syntax . "#. read-time eval")
|
|
20
|
-
(:defmacro . "defmacro")
|
|
21
|
-
(:trailing-ws . "trailing whitespace")
|
|
22
|
-
(:ok . "OK")
|
|
23
|
-
(:fail . "FAIL")
|
|
24
|
-
(:header . " @lisp SBCL Lint")
|
|
25
|
-
(:source . " Source")
|
|
26
|
-
(:found . " Found ~d .lsp files")
|
|
27
|
-
(:scanned . " Scanned")
|
|
28
|
-
(:errors . " Errors")
|
|
29
|
-
(:warnings . " Warnings"))
|
|
30
|
-
'((:not-found . "not found symbol")
|
|
31
|
-
(:syntax-error . "syntax error")
|
|
32
|
-
(:vec-syntax . "#( vector syntax")
|
|
33
|
-
(:char-syntax . "# backslash char literal")
|
|
34
|
-
(:eval-syntax . "#. read-time eval")
|
|
35
|
-
(:defmacro . "defmacro")
|
|
36
|
-
(:trailing-ws . "trailing whitespace")
|
|
37
|
-
(:ok . "OK")
|
|
38
|
-
(:fail . "FAIL")
|
|
39
|
-
(:header . " @lisp SBCL Lint")
|
|
40
|
-
(:source . " Source")
|
|
41
|
-
(:found . " Found ~d .lsp files")
|
|
42
|
-
(:scanned . " Scanned")
|
|
43
|
-
(:errors . " Errors")
|
|
44
|
-
(:warnings . " Warnings"))))))
|
|
45
9
|
|
|
46
10
|
;; ── Stub packages from external file ──────────────────────────────────
|
|
11
|
+
;; File format: alist ((name use*) ...) — valid Lisp data
|
|
47
12
|
(defun load-stub-packages (file-path)
|
|
48
13
|
(flet ((ensure-pkg (name &optional use-list)
|
|
49
14
|
(unless (find-package name)
|
|
@@ -87,10 +52,11 @@
|
|
|
87
52
|
(let ((msg (princ-to-string e)))
|
|
88
53
|
(cond
|
|
89
54
|
((search "not found" msg)
|
|
90
|
-
(format t "~% [NOTE] ~a: ~a~%" rel
|
|
55
|
+
(format t "~% [NOTE] ~a: ~a~%" rel
|
|
56
|
+
(subseq msg 0 (min 80 (length msg))))
|
|
91
57
|
(incf *warnings*))
|
|
92
58
|
(t
|
|
93
|
-
(format t "
|
|
59
|
+
(format t "FAIL~% [ERROR] ~a: ~a~%" rel e)
|
|
94
60
|
(incf *errors*)
|
|
95
61
|
(return-from check-file))))))
|
|
96
62
|
;; Trailing whitespace
|
|
@@ -101,7 +67,7 @@
|
|
|
101
67
|
when (and (> (length line) 0)
|
|
102
68
|
(find (char line (1- (length line))) '(#\Space #\Tab)))
|
|
103
69
|
do (progn
|
|
104
|
-
(format t "~% [WARN] ~a line ~d:
|
|
70
|
+
(format t "~% [WARN] ~a line ~d: trailing whitespace~%" rel lineno)
|
|
105
71
|
(incf *warnings*))))
|
|
106
72
|
;; CL-ism checks: raw content scan
|
|
107
73
|
(with-open-file (s path :direction :input)
|
|
@@ -109,19 +75,19 @@
|
|
|
109
75
|
(file-position s 0)
|
|
110
76
|
(read-sequence content s)
|
|
111
77
|
(when (search "#(" content)
|
|
112
|
-
(format t "~% [WARN] ~a:
|
|
78
|
+
(format t "~% [WARN] ~a: #( vector syntax (not valid in AutoLISP)~%" rel)
|
|
113
79
|
(incf *warnings*))
|
|
114
80
|
(when (search "#\\" content)
|
|
115
|
-
(format t "~% [WARN] ~a:
|
|
81
|
+
(format t "~% [WARN] ~a: #\\ character literal syntax (not valid in AutoLISP)~%" rel)
|
|
116
82
|
(incf *warnings*))
|
|
117
83
|
(when (search "#." content)
|
|
118
|
-
(format t "~% [WARN] ~a:
|
|
84
|
+
(format t "~% [WARN] ~a: #. read-time eval syntax (not valid in AutoLISP)~%" rel)
|
|
119
85
|
(incf *warnings*))
|
|
120
86
|
(when (and (search "defmacro" content)
|
|
121
87
|
(not (some (lambda (s) (search s fullname)) defmacro-allow-files)))
|
|
122
|
-
(format t "~% [WARN] ~a:
|
|
88
|
+
(format t "~% [WARN] ~a: defmacro (not valid in AutoLISP)~%" rel)
|
|
123
89
|
(incf *warnings*))))
|
|
124
|
-
(format t "
|
|
90
|
+
(format t "OK~%")))
|
|
125
91
|
|
|
126
92
|
;; ── Main ──────────────────────────────────────────────────────────────
|
|
127
93
|
(defun main ()
|
|
@@ -133,26 +99,25 @@
|
|
|
133
99
|
'(".vscode" "test" "experiment" "tools" ".git")))
|
|
134
100
|
(defmacro-allow (if (fourth args)
|
|
135
101
|
(read-from-string (fourth args))
|
|
136
|
-
'("compat-cl")))
|
|
137
|
-
|
|
138
|
-
(when locale (setf *locale* locale))
|
|
102
|
+
'("compat-cl"))))
|
|
103
|
+
;; Load stub packages for CAD runtime symbols
|
|
139
104
|
(load-stub-packages stub-file)
|
|
140
105
|
|
|
141
106
|
(format t "~%==================================================~%")
|
|
142
|
-
(format t "
|
|
143
|
-
(format t "
|
|
107
|
+
(format t " @lisp SBCL Lint~%")
|
|
108
|
+
(format t " Source: ~a~%" (namestring (pathname src-dir)))
|
|
144
109
|
(format t "==================================================~%~%")
|
|
145
110
|
(setf *errors* 0 *warnings* 0 *checked* 0)
|
|
146
111
|
|
|
147
112
|
(let ((files (walk-tree src-dir walk-exclude)))
|
|
148
|
-
(format t "~
|
|
113
|
+
(format t " Found ~d .lsp files~%~%" (length files))
|
|
149
114
|
(dolist (f files)
|
|
150
115
|
(check-file f src-dir defmacro-allow)))
|
|
151
116
|
|
|
152
117
|
(format t "~%==================================================~%")
|
|
153
|
-
(format t "
|
|
154
|
-
(format t "
|
|
155
|
-
(format t "
|
|
118
|
+
(format t " Scanned: ~d files~%" *checked*)
|
|
119
|
+
(format t " Errors: ~d~%" *errors*)
|
|
120
|
+
(format t " Warnings: ~d~%" *warnings*)
|
|
156
121
|
(format t "==================================================~%~%")
|
|
157
122
|
(if (> *errors* 0)
|
|
158
123
|
(uiop:quit 1)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlisp/lint",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "AutoLISP static analysis tool — parens, security, conventions, SBCL syntax validation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CAD",
|
|
@@ -17,22 +17,36 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist/",
|
|
20
|
+
"!dist/**/*.map",
|
|
20
21
|
"lib/",
|
|
21
22
|
"bin/",
|
|
22
23
|
"atlisp-lint.default.json",
|
|
23
|
-
"stub-packages.json"
|
|
24
|
-
"pre-commit/"
|
|
24
|
+
"stub-packages.json"
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "tsc
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"clean": "rm -rf dist",
|
|
28
29
|
"test": "jest",
|
|
30
|
+
"test:coverage": "jest --coverage",
|
|
31
|
+
"test:watch": "jest --watch",
|
|
32
|
+
"lint": "eslint src",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
35
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
29
36
|
"prepublishOnly": "npm run build",
|
|
30
37
|
"prepack": "npm run build"
|
|
31
38
|
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@atlisp/parser": "^0.1.0"
|
|
41
|
+
},
|
|
32
42
|
"devDependencies": {
|
|
33
43
|
"@types/jest": "^29",
|
|
34
44
|
"@types/node": "^18",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^7",
|
|
46
|
+
"@typescript-eslint/parser": "^7",
|
|
47
|
+
"eslint": "^8",
|
|
35
48
|
"jest": "^29",
|
|
49
|
+
"prettier": "^3",
|
|
36
50
|
"ts-jest": "^29",
|
|
37
51
|
"ts-node": "^10.9.2",
|
|
38
52
|
"typescript": "^5"
|