@rcrsr/rill 0.1.0 → 0.2.0
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 +16 -8
- package/dist/check/config.d.ts +20 -0
- package/dist/check/config.d.ts.map +1 -0
- package/dist/check/config.js +151 -0
- package/dist/check/config.js.map +1 -0
- package/dist/check/fixer.d.ts +39 -0
- package/dist/check/fixer.d.ts.map +1 -0
- package/dist/check/fixer.js +119 -0
- package/dist/check/fixer.js.map +1 -0
- package/dist/check/index.d.ts +10 -0
- package/dist/check/index.d.ts.map +1 -0
- package/dist/check/index.js +21 -0
- package/dist/check/index.js.map +1 -0
- package/dist/check/rules/anti-patterns.d.ts +65 -0
- package/dist/check/rules/anti-patterns.d.ts.map +1 -0
- package/dist/check/rules/anti-patterns.js +427 -0
- package/dist/check/rules/anti-patterns.js.map +1 -0
- package/dist/check/rules/closures.d.ts +66 -0
- package/dist/check/rules/closures.d.ts.map +1 -0
- package/dist/check/rules/closures.js +373 -0
- package/dist/check/rules/closures.js.map +1 -0
- package/dist/check/rules/collections.d.ts +90 -0
- package/dist/check/rules/collections.d.ts.map +1 -0
- package/dist/check/rules/collections.js +373 -0
- package/dist/check/rules/collections.js.map +1 -0
- package/dist/check/rules/conditionals.d.ts +41 -0
- package/dist/check/rules/conditionals.d.ts.map +1 -0
- package/dist/check/rules/conditionals.js +106 -0
- package/dist/check/rules/conditionals.js.map +1 -0
- package/dist/check/rules/flow.d.ts +46 -0
- package/dist/check/rules/flow.d.ts.map +1 -0
- package/dist/check/rules/flow.js +206 -0
- package/dist/check/rules/flow.js.map +1 -0
- package/dist/check/rules/formatting.d.ts +133 -0
- package/dist/check/rules/formatting.d.ts.map +1 -0
- package/dist/check/rules/formatting.js +639 -0
- package/dist/check/rules/formatting.js.map +1 -0
- package/dist/check/rules/helpers.d.ts +26 -0
- package/dist/check/rules/helpers.d.ts.map +1 -0
- package/dist/check/rules/helpers.js +66 -0
- package/dist/check/rules/helpers.js.map +1 -0
- package/dist/check/rules/index.d.ts +21 -0
- package/dist/check/rules/index.d.ts.map +1 -0
- package/dist/check/rules/index.js +78 -0
- package/dist/check/rules/index.js.map +1 -0
- package/dist/check/rules/loops.d.ts +70 -0
- package/dist/check/rules/loops.d.ts.map +1 -0
- package/dist/check/rules/loops.js +227 -0
- package/dist/check/rules/loops.js.map +1 -0
- package/dist/check/rules/naming.d.ts +21 -0
- package/dist/check/rules/naming.d.ts.map +1 -0
- package/dist/check/rules/naming.js +167 -0
- package/dist/check/rules/naming.js.map +1 -0
- package/dist/check/rules/strings.d.ts +28 -0
- package/dist/check/rules/strings.d.ts.map +1 -0
- package/dist/check/rules/strings.js +80 -0
- package/dist/check/rules/strings.js.map +1 -0
- package/dist/check/rules/types.d.ts +41 -0
- package/dist/check/rules/types.d.ts.map +1 -0
- package/dist/check/rules/types.js +162 -0
- package/dist/check/rules/types.js.map +1 -0
- package/dist/check/types.d.ts +106 -0
- package/dist/check/types.d.ts.map +1 -0
- package/dist/check/types.js +6 -0
- package/dist/check/types.js.map +1 -0
- package/dist/check/validator.d.ts +18 -0
- package/dist/check/validator.d.ts.map +1 -0
- package/dist/check/validator.js +88 -0
- package/dist/check/validator.js.map +1 -0
- package/dist/check/visitor.d.ts +33 -0
- package/dist/check/visitor.d.ts.map +1 -0
- package/dist/check/visitor.js +243 -0
- package/dist/check/visitor.js.map +1 -0
- package/dist/cli-check.d.ts +43 -0
- package/dist/cli-check.d.ts.map +1 -0
- package/dist/cli-check.js +356 -0
- package/dist/cli-check.js.map +1 -0
- package/dist/cli-eval.d.ts +15 -0
- package/dist/cli-eval.d.ts.map +1 -0
- package/dist/cli-eval.js +120 -0
- package/dist/cli-eval.js.map +1 -0
- package/dist/cli-exec.d.ts +49 -0
- package/dist/cli-exec.d.ts.map +1 -0
- package/dist/cli-exec.js +191 -0
- package/dist/cli-exec.js.map +1 -0
- package/dist/cli-module-loader.d.ts +19 -0
- package/dist/cli-module-loader.d.ts.map +1 -0
- package/dist/cli-module-loader.js +83 -0
- package/dist/cli-module-loader.js.map +1 -0
- package/dist/cli-shared.d.ts +36 -0
- package/dist/cli-shared.d.ts.map +1 -0
- package/dist/cli-shared.js +101 -0
- package/dist/cli-shared.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lexer/readers.d.ts +1 -1
- package/dist/lexer/readers.d.ts.map +1 -1
- package/dist/lexer/readers.js +62 -32
- package/dist/lexer/readers.js.map +1 -1
- package/dist/lexer/tokenizer.d.ts.map +1 -1
- package/dist/lexer/tokenizer.js +5 -6
- package/dist/lexer/tokenizer.js.map +1 -1
- package/dist/parser/index.js +1 -1
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/parser-expr.js +23 -5
- package/dist/parser/parser-expr.js.map +1 -1
- package/dist/parser/parser-functions.d.ts +2 -2
- package/dist/parser/parser-functions.d.ts.map +1 -1
- package/dist/parser/parser-functions.js +2 -1
- package/dist/parser/parser-functions.js.map +1 -1
- package/dist/parser/parser-literals.js +2 -2
- package/dist/parser/parser-literals.js.map +1 -1
- package/dist/parser/parser-script.js +9 -7
- package/dist/parser/parser-script.js.map +1 -1
- package/dist/parser/parser-variables.js +4 -3
- package/dist/parser/parser-variables.js.map +1 -1
- package/dist/runtime/core/callable.d.ts +5 -6
- package/dist/runtime/core/callable.d.ts.map +1 -1
- package/dist/runtime/core/callable.js.map +1 -1
- package/dist/runtime/core/context.d.ts.map +1 -1
- package/dist/runtime/core/context.js +19 -32
- package/dist/runtime/core/context.js.map +1 -1
- package/dist/runtime/core/equals.js +1 -1
- package/dist/runtime/core/equals.js.map +1 -1
- package/dist/runtime/core/eval/evaluator.d.ts +78 -0
- package/dist/runtime/core/eval/evaluator.d.ts.map +1 -1
- package/dist/runtime/core/eval/evaluator.js +78 -0
- package/dist/runtime/core/eval/evaluator.js.map +1 -1
- package/dist/runtime/core/eval/mixins/closures.d.ts.map +1 -1
- package/dist/runtime/core/eval/mixins/closures.js +9 -1
- package/dist/runtime/core/eval/mixins/closures.js.map +1 -1
- package/dist/runtime/core/eval/mixins/variables.d.ts.map +1 -1
- package/dist/runtime/core/eval/mixins/variables.js +143 -2
- package/dist/runtime/core/eval/mixins/variables.js.map +1 -1
- package/dist/runtime/core/types.d.ts +15 -2
- package/dist/runtime/core/types.d.ts.map +1 -1
- package/dist/runtime/core/types.js.map +1 -1
- package/dist/runtime/ext/extensions.d.ts +51 -0
- package/dist/runtime/ext/extensions.d.ts.map +1 -0
- package/dist/runtime/ext/extensions.js +67 -0
- package/dist/runtime/ext/extensions.js.map +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/types.d.ts +8 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -4
- package/dist/types.js.map +1 -1
- package/docs/00_INDEX.md +1 -0
- package/docs/01_guide.md +3 -3
- package/docs/02_types.md +8 -10
- package/docs/03_variables.md +10 -0
- package/docs/04_operators.md +3 -3
- package/docs/05_control-flow.md +21 -0
- package/docs/07_collections.md +2 -0
- package/docs/10_parsing.md +9 -9
- package/docs/11_reference.md +1 -1
- package/docs/12_examples.md +36 -62
- package/docs/14_host-integration.md +116 -111
- package/docs/15_grammar.ebnf +1 -5
- package/docs/16_conventions.md +3 -4
- package/docs/17_cli-tools.md +184 -0
- package/docs/99_llm-reference.txt +46 -5
- package/package.json +13 -4
- package/dist/demo.d.ts +0 -6
- package/dist/demo.d.ts.map +0 -1
- package/dist/demo.js +0 -121
- package/dist/demo.js.map +0 -1
- package/dist/lexer.d.ts +0 -19
- package/dist/lexer.d.ts.map +0 -1
- package/dist/lexer.js +0 -344
- package/dist/lexer.js.map +0 -1
- package/dist/parser/arithmetic.d.ts +0 -16
- package/dist/parser/arithmetic.d.ts.map +0 -1
- package/dist/parser/arithmetic.js +0 -128
- package/dist/parser/arithmetic.js.map +0 -1
- package/dist/parser/boolean.d.ts +0 -15
- package/dist/parser/boolean.d.ts.map +0 -1
- package/dist/parser/boolean.js +0 -20
- package/dist/parser/boolean.js.map +0 -1
- package/dist/parser/control-flow.d.ts +0 -56
- package/dist/parser/control-flow.d.ts.map +0 -1
- package/dist/parser/control-flow.js +0 -167
- package/dist/parser/control-flow.js.map +0 -1
- package/dist/parser/expressions.d.ts +0 -23
- package/dist/parser/expressions.d.ts.map +0 -1
- package/dist/parser/expressions.js +0 -950
- package/dist/parser/expressions.js.map +0 -1
- package/dist/parser/extraction.d.ts +0 -48
- package/dist/parser/extraction.d.ts.map +0 -1
- package/dist/parser/extraction.js +0 -279
- package/dist/parser/extraction.js.map +0 -1
- package/dist/parser/functions.d.ts +0 -20
- package/dist/parser/functions.d.ts.map +0 -1
- package/dist/parser/functions.js +0 -96
- package/dist/parser/functions.js.map +0 -1
- package/dist/parser/literals.d.ts +0 -37
- package/dist/parser/literals.d.ts.map +0 -1
- package/dist/parser/literals.js +0 -373
- package/dist/parser/literals.js.map +0 -1
- package/dist/parser/script.d.ts +0 -14
- package/dist/parser/script.d.ts.map +0 -1
- package/dist/parser/script.js +0 -196
- package/dist/parser/script.js.map +0 -1
- package/dist/parser/variables.d.ts +0 -10
- package/dist/parser/variables.d.ts.map +0 -1
- package/dist/parser/variables.js +0 -215
- package/dist/parser/variables.js.map +0 -1
- package/dist/runtime/ast-equals.d.ts +0 -13
- package/dist/runtime/ast-equals.d.ts.map +0 -1
- package/dist/runtime/ast-equals.js +0 -447
- package/dist/runtime/ast-equals.js.map +0 -1
- package/dist/runtime/builtins.d.ts +0 -13
- package/dist/runtime/builtins.d.ts.map +0 -1
- package/dist/runtime/builtins.js +0 -180
- package/dist/runtime/builtins.js.map +0 -1
- package/dist/runtime/callable.d.ts +0 -88
- package/dist/runtime/callable.d.ts.map +0 -1
- package/dist/runtime/callable.js +0 -98
- package/dist/runtime/callable.js.map +0 -1
- package/dist/runtime/context.d.ts +0 -13
- package/dist/runtime/context.d.ts.map +0 -1
- package/dist/runtime/context.js +0 -73
- package/dist/runtime/context.js.map +0 -1
- package/dist/runtime/core/evaluate.d.ts +0 -42
- package/dist/runtime/core/evaluate.d.ts.map +0 -1
- package/dist/runtime/core/evaluate.debug.js +0 -1251
- package/dist/runtime/core/evaluate.js +0 -1913
- package/dist/runtime/core/evaluate.js.map +0 -1
- package/dist/runtime/evaluate.d.ts +0 -32
- package/dist/runtime/evaluate.d.ts.map +0 -1
- package/dist/runtime/evaluate.js +0 -1111
- package/dist/runtime/evaluate.js.map +0 -1
- package/dist/runtime/execute.d.ts +0 -26
- package/dist/runtime/execute.d.ts.map +0 -1
- package/dist/runtime/execute.js +0 -121
- package/dist/runtime/execute.js.map +0 -1
- package/dist/runtime/signals.d.ts +0 -19
- package/dist/runtime/signals.d.ts.map +0 -1
- package/dist/runtime/signals.js +0 -26
- package/dist/runtime/signals.js.map +0 -1
- package/dist/runtime/types.d.ts +0 -169
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js +0 -50
- package/dist/runtime/types.js.map +0 -1
- package/dist/runtime/values.d.ts +0 -50
- package/dist/runtime/values.d.ts.map +0 -1
- package/dist/runtime/values.js +0 -209
- package/dist/runtime/values.js.map +0 -1
- package/dist/runtime.d.ts +0 -254
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -2014
- package/dist/runtime.js.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naming Convention Rules
|
|
3
|
+
* Enforces snake_case naming for variables, parameters, and dict keys.
|
|
4
|
+
*/
|
|
5
|
+
import { extractContextLine } from './helpers.js';
|
|
6
|
+
// ============================================================
|
|
7
|
+
// NAMING VALIDATION
|
|
8
|
+
// ============================================================
|
|
9
|
+
/**
|
|
10
|
+
* Check if a name follows snake_case convention.
|
|
11
|
+
* Valid: user_name, item_list, is_valid, x, count
|
|
12
|
+
* Invalid: userName, ItemList, user-name, user.name
|
|
13
|
+
*/
|
|
14
|
+
function isSnakeCase(name) {
|
|
15
|
+
// Empty string is invalid
|
|
16
|
+
if (!name)
|
|
17
|
+
return false;
|
|
18
|
+
// Must match: lowercase letters, numbers, underscores only
|
|
19
|
+
// Must start with letter or underscore
|
|
20
|
+
// No consecutive underscores, no trailing underscore
|
|
21
|
+
const snakeCasePattern = /^[a-z_][a-z0-9_]*$/;
|
|
22
|
+
if (!snakeCasePattern.test(name))
|
|
23
|
+
return false;
|
|
24
|
+
// Reject consecutive underscores
|
|
25
|
+
if (name.includes('__'))
|
|
26
|
+
return false;
|
|
27
|
+
// Reject trailing underscore (unless single underscore)
|
|
28
|
+
if (name.length > 1 && name.endsWith('_'))
|
|
29
|
+
return false;
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert a name to snake_case.
|
|
34
|
+
* Handles camelCase, PascalCase, kebab-case, and mixed formats.
|
|
35
|
+
*/
|
|
36
|
+
function toSnakeCase(name) {
|
|
37
|
+
return (name
|
|
38
|
+
// Handle consecutive uppercase (XMLParser -> xml_parser)
|
|
39
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
|
40
|
+
// Insert underscore before uppercase letters (camelCase -> camel_case)
|
|
41
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
42
|
+
// Replace hyphens and dots with underscores
|
|
43
|
+
.replace(/[-.\s]+/g, '_')
|
|
44
|
+
// Convert to lowercase
|
|
45
|
+
.toLowerCase()
|
|
46
|
+
// Remove consecutive underscores
|
|
47
|
+
.replace(/_+/g, '_')
|
|
48
|
+
// Remove leading/trailing underscores
|
|
49
|
+
.replace(/^_+|_+$/g, ''));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a diagnostic for snake_case violation.
|
|
53
|
+
*/
|
|
54
|
+
function createNamingDiagnostic(location, name, kind, context, fix) {
|
|
55
|
+
const message = `${kind} '${name}' should use snake_case (e.g., '${toSnakeCase(name)}')`;
|
|
56
|
+
return {
|
|
57
|
+
location,
|
|
58
|
+
severity: 'error',
|
|
59
|
+
code: 'NAMING_SNAKE_CASE',
|
|
60
|
+
message,
|
|
61
|
+
context: extractContextLine(location.line, context.source),
|
|
62
|
+
fix,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// ============================================================
|
|
66
|
+
// NAMING_SNAKE_CASE RULE
|
|
67
|
+
// ============================================================
|
|
68
|
+
/**
|
|
69
|
+
* Validates that variable definitions, parameters, and dict keys use snake_case.
|
|
70
|
+
*
|
|
71
|
+
* Checks definition sites only (not variable usage):
|
|
72
|
+
* - Captures: :> $user_name, :> $item_list, :> $is_valid
|
|
73
|
+
* - Closure params: |user_name, count| { }
|
|
74
|
+
* - Dict keys: [user_name: "Alice", is_active: true]
|
|
75
|
+
*
|
|
76
|
+
* Exceptions:
|
|
77
|
+
* - Single-letter names are valid (common for loop variables)
|
|
78
|
+
*
|
|
79
|
+
* References:
|
|
80
|
+
* - docs/16_conventions.md:10-53
|
|
81
|
+
*/
|
|
82
|
+
export const NAMING_SNAKE_CASE = {
|
|
83
|
+
code: 'NAMING_SNAKE_CASE',
|
|
84
|
+
category: 'naming',
|
|
85
|
+
severity: 'error',
|
|
86
|
+
nodeTypes: ['ClosureParam', 'DictEntry', 'Capture'],
|
|
87
|
+
validate(node, context) {
|
|
88
|
+
switch (node.type) {
|
|
89
|
+
case 'ClosureParam': {
|
|
90
|
+
const paramNode = node;
|
|
91
|
+
const name = paramNode.name;
|
|
92
|
+
if (!isSnakeCase(name)) {
|
|
93
|
+
const fix = this.fix?.(node, context) ?? null;
|
|
94
|
+
return [
|
|
95
|
+
createNamingDiagnostic(paramNode.span.start, name, 'Parameter', context, fix),
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
case 'DictEntry': {
|
|
101
|
+
const entryNode = node;
|
|
102
|
+
const key = entryNode.key;
|
|
103
|
+
if (!isSnakeCase(key)) {
|
|
104
|
+
const fix = this.fix?.(node, context) ?? null;
|
|
105
|
+
return [
|
|
106
|
+
createNamingDiagnostic(entryNode.span.start, key, 'Dict key', context, fix),
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
case 'Capture': {
|
|
112
|
+
const captureNode = node;
|
|
113
|
+
const name = captureNode.name;
|
|
114
|
+
if (!isSnakeCase(name)) {
|
|
115
|
+
const fix = this.fix?.(node, context) ?? null;
|
|
116
|
+
return [
|
|
117
|
+
createNamingDiagnostic(captureNode.span.start, name, 'Captured variable', context, fix),
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
default:
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
fix(node, context) {
|
|
127
|
+
let name = null;
|
|
128
|
+
let range = node.span;
|
|
129
|
+
// Extract name and determine replacement range
|
|
130
|
+
switch (node.type) {
|
|
131
|
+
case 'ClosureParam': {
|
|
132
|
+
const paramNode = node;
|
|
133
|
+
name = paramNode.name;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'DictEntry': {
|
|
137
|
+
const entryNode = node;
|
|
138
|
+
name = entryNode.key;
|
|
139
|
+
// For dict entries, replace only the key portion before the colon
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case 'Capture': {
|
|
143
|
+
const captureNode = node;
|
|
144
|
+
name = captureNode.name;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
default:
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
if (!name || isSnakeCase(name)) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const snakeCaseName = toSnakeCase(name);
|
|
154
|
+
// Get original source text for this node
|
|
155
|
+
const sourceText = context.source.substring(range.start.offset, range.end.offset);
|
|
156
|
+
// Replace the original name with snake_case version
|
|
157
|
+
// This preserves $ prefix for variables and : for dict entries
|
|
158
|
+
const replacement = sourceText.replace(name, snakeCaseName);
|
|
159
|
+
return {
|
|
160
|
+
description: `Rename '${name}' to '${snakeCaseName}'`,
|
|
161
|
+
applicable: true,
|
|
162
|
+
range,
|
|
163
|
+
replacement,
|
|
164
|
+
};
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/check/rules/naming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String Handling Convention Rules
|
|
3
|
+
* Enforces string handling best practices from docs/16_conventions.md:318-352.
|
|
4
|
+
*/
|
|
5
|
+
import type { ValidationRule } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Enforces .empty method for emptiness checks.
|
|
8
|
+
* Direct string comparison with "" is not idiomatic and may not work
|
|
9
|
+
* correctly in all contexts. Use .empty method instead.
|
|
10
|
+
*
|
|
11
|
+
* Detection:
|
|
12
|
+
* - BinaryExpr with == or != operator
|
|
13
|
+
* - One side is empty string literal ""
|
|
14
|
+
* - Suggests using .empty method
|
|
15
|
+
*
|
|
16
|
+
* Valid patterns:
|
|
17
|
+
* - $str -> .empty (check if empty)
|
|
18
|
+
* - $str -> .empty ? "yes" ! "no" (conditional)
|
|
19
|
+
*
|
|
20
|
+
* Discouraged:
|
|
21
|
+
* - $str == "" (direct comparison)
|
|
22
|
+
* - $str != "" (direct comparison)
|
|
23
|
+
*
|
|
24
|
+
* References:
|
|
25
|
+
* - docs/16_conventions.md:333-345
|
|
26
|
+
*/
|
|
27
|
+
export declare const USE_EMPTY_METHOD: ValidationRule;
|
|
28
|
+
//# sourceMappingURL=strings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../../src/check/rules/strings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,aAAa,CAAC;AAYrB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,gBAAgB,EAAE,cA2C9B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String Handling Convention Rules
|
|
3
|
+
* Enforces string handling best practices from docs/16_conventions.md:318-352.
|
|
4
|
+
*/
|
|
5
|
+
import { extractContextLine } from './helpers.js';
|
|
6
|
+
// ============================================================
|
|
7
|
+
// USE_EMPTY_METHOD RULE
|
|
8
|
+
// ============================================================
|
|
9
|
+
/**
|
|
10
|
+
* Enforces .empty method for emptiness checks.
|
|
11
|
+
* Direct string comparison with "" is not idiomatic and may not work
|
|
12
|
+
* correctly in all contexts. Use .empty method instead.
|
|
13
|
+
*
|
|
14
|
+
* Detection:
|
|
15
|
+
* - BinaryExpr with == or != operator
|
|
16
|
+
* - One side is empty string literal ""
|
|
17
|
+
* - Suggests using .empty method
|
|
18
|
+
*
|
|
19
|
+
* Valid patterns:
|
|
20
|
+
* - $str -> .empty (check if empty)
|
|
21
|
+
* - $str -> .empty ? "yes" ! "no" (conditional)
|
|
22
|
+
*
|
|
23
|
+
* Discouraged:
|
|
24
|
+
* - $str == "" (direct comparison)
|
|
25
|
+
* - $str != "" (direct comparison)
|
|
26
|
+
*
|
|
27
|
+
* References:
|
|
28
|
+
* - docs/16_conventions.md:333-345
|
|
29
|
+
*/
|
|
30
|
+
export const USE_EMPTY_METHOD = {
|
|
31
|
+
code: 'USE_EMPTY_METHOD',
|
|
32
|
+
category: 'strings',
|
|
33
|
+
severity: 'warning',
|
|
34
|
+
nodeTypes: ['BinaryExpr'],
|
|
35
|
+
validate(node, context) {
|
|
36
|
+
const binaryNode = node;
|
|
37
|
+
// Only check equality operators
|
|
38
|
+
if (binaryNode.op !== '==' && binaryNode.op !== '!=') {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
// left and right are PostfixExpr - check their primaries
|
|
42
|
+
const left = binaryNode.left;
|
|
43
|
+
const right = binaryNode.right;
|
|
44
|
+
const leftIsEmpty = left.type === 'PostfixExpr' && isEmptyStringLiteral(left.primary);
|
|
45
|
+
const rightIsEmpty = right.type === 'PostfixExpr' && isEmptyStringLiteral(right.primary);
|
|
46
|
+
if (leftIsEmpty || rightIsEmpty) {
|
|
47
|
+
const suggestedMethod = binaryNode.op === '==' ? '.empty' : '.empty -> !';
|
|
48
|
+
return [
|
|
49
|
+
{
|
|
50
|
+
location: binaryNode.span.start,
|
|
51
|
+
severity: 'warning',
|
|
52
|
+
code: 'USE_EMPTY_METHOD',
|
|
53
|
+
message: `Use ${suggestedMethod} for emptiness checks instead of comparing with ""`,
|
|
54
|
+
context: extractContextLine(binaryNode.span.start.line, context.source),
|
|
55
|
+
fix: null, // Auto-fix would require expression reconstruction
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
return [];
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Check if a node is an empty string literal.
|
|
64
|
+
*/
|
|
65
|
+
function isEmptyStringLiteral(node) {
|
|
66
|
+
if (node.type !== 'StringLiteral') {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const stringNode = node;
|
|
70
|
+
// Check if all parts are empty strings (no interpolations)
|
|
71
|
+
if (stringNode.parts.length === 0) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
if (stringNode.parts.length === 1) {
|
|
75
|
+
const part = stringNode.parts[0];
|
|
76
|
+
return typeof part === 'string' && part === '';
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../../../src/check/rules/strings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,+DAA+D;AAC/D,wBAAwB;AACxB,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,CAAC,YAAY,CAAC;IAEzB,QAAQ,CAAC,IAAa,EAAE,OAA0B;QAChD,MAAM,UAAU,GAAG,IAAsB,CAAC;QAE1C,gCAAgC;QAChC,IAAI,UAAU,CAAC,EAAE,KAAK,IAAI,IAAI,UAAU,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,yDAAyD;QACzD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAW,CAAC;QACpC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAY,CAAC;QAEtC,MAAM,WAAW,GACf,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpE,MAAM,YAAY,GAChB,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtE,IAAI,WAAW,IAAI,YAAY,EAAE,CAAC;YAChC,MAAM,eAAe,GAAG,UAAU,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;YAE1E,OAAO;gBACL;oBACE,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK;oBAC/B,QAAQ,EAAE,SAAS;oBACnB,IAAI,EAAE,kBAAkB;oBACxB,OAAO,EAAE,OAAO,eAAe,oDAAoD;oBACnF,OAAO,EAAE,kBAAkB,CACzB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAC1B,OAAO,CAAC,MAAM,CACf;oBACD,GAAG,EAAE,IAAI,EAAE,mDAAmD;iBAC/D;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC;AAEF;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAa;IACzC,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,UAAU,GAAG,IAAyB,CAAC;IAE7C,2DAA2D;IAC3D,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE,CAAC;IACjD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Safety Convention Rules
|
|
3
|
+
* Enforces type annotation best practices from docs/16_conventions.md:288-316.
|
|
4
|
+
*/
|
|
5
|
+
import type { ValidationRule } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Detects redundant type assertions on literal values.
|
|
8
|
+
* Type assertions are for validation, not conversion. Asserting a literal's
|
|
9
|
+
* type is unnecessary because the type is already known at parse time.
|
|
10
|
+
*
|
|
11
|
+
* Redundant patterns:
|
|
12
|
+
* - 5:number (number literal with number assertion)
|
|
13
|
+
* - "hello":string (string literal with string assertion)
|
|
14
|
+
* - true:bool (bool literal with bool assertion)
|
|
15
|
+
*
|
|
16
|
+
* Valid patterns:
|
|
17
|
+
* - parseJson($input):dict (external input validation)
|
|
18
|
+
* - $userInput:string (runtime validation)
|
|
19
|
+
*
|
|
20
|
+
* References:
|
|
21
|
+
* - docs/16_conventions.md:305-315
|
|
22
|
+
*/
|
|
23
|
+
export declare const UNNECESSARY_ASSERTION: ValidationRule;
|
|
24
|
+
/**
|
|
25
|
+
* Recommends type assertions for external input validation.
|
|
26
|
+
* External inputs (from host functions, user input, parsed data) should be
|
|
27
|
+
* validated with type assertions to ensure type safety.
|
|
28
|
+
*
|
|
29
|
+
* Detection heuristics:
|
|
30
|
+
* - Host function calls (HostCall nodes)
|
|
31
|
+
* - Parsing functions (parse_json, parse_xml, etc.)
|
|
32
|
+
* - Variables from external sources ($ARGS, $ENV)
|
|
33
|
+
*
|
|
34
|
+
* This is an informational rule - not all external data needs assertions,
|
|
35
|
+
* but it's a good practice for critical paths.
|
|
36
|
+
*
|
|
37
|
+
* References:
|
|
38
|
+
* - docs/16_conventions.md:307-311
|
|
39
|
+
*/
|
|
40
|
+
export declare const VALIDATE_EXTERNAL: ValidationRule;
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/check/rules/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,cAAc,EAKf,MAAM,aAAa,CAAC;AAQrB;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB,EAAE,cAwFnC,CAAC;AA4BF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,EAAE,cAuC/B,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Safety Convention Rules
|
|
3
|
+
* Enforces type annotation best practices from docs/16_conventions.md:288-316.
|
|
4
|
+
*/
|
|
5
|
+
import { extractContextLine } from './helpers.js';
|
|
6
|
+
// ============================================================
|
|
7
|
+
// UNNECESSARY_ASSERTION RULE
|
|
8
|
+
// ============================================================
|
|
9
|
+
/**
|
|
10
|
+
* Detects redundant type assertions on literal values.
|
|
11
|
+
* Type assertions are for validation, not conversion. Asserting a literal's
|
|
12
|
+
* type is unnecessary because the type is already known at parse time.
|
|
13
|
+
*
|
|
14
|
+
* Redundant patterns:
|
|
15
|
+
* - 5:number (number literal with number assertion)
|
|
16
|
+
* - "hello":string (string literal with string assertion)
|
|
17
|
+
* - true:bool (bool literal with bool assertion)
|
|
18
|
+
*
|
|
19
|
+
* Valid patterns:
|
|
20
|
+
* - parseJson($input):dict (external input validation)
|
|
21
|
+
* - $userInput:string (runtime validation)
|
|
22
|
+
*
|
|
23
|
+
* References:
|
|
24
|
+
* - docs/16_conventions.md:305-315
|
|
25
|
+
*/
|
|
26
|
+
export const UNNECESSARY_ASSERTION = {
|
|
27
|
+
code: 'UNNECESSARY_ASSERTION',
|
|
28
|
+
category: 'types',
|
|
29
|
+
severity: 'info',
|
|
30
|
+
nodeTypes: ['TypeAssertion'],
|
|
31
|
+
validate(node, context) {
|
|
32
|
+
const assertionNode = node;
|
|
33
|
+
const operand = assertionNode.operand;
|
|
34
|
+
// Bare assertions (:type) are valid - they check pipe value
|
|
35
|
+
if (!operand) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
// operand is PostfixExprNode - check the primary
|
|
39
|
+
const primary = operand.primary;
|
|
40
|
+
// Check if primary is a literal
|
|
41
|
+
const isLiteral = primary.type === 'NumberLiteral' ||
|
|
42
|
+
primary.type === 'StringLiteral' ||
|
|
43
|
+
primary.type === 'BoolLiteral';
|
|
44
|
+
if (!isLiteral) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
// Check if the assertion matches the literal type
|
|
48
|
+
const literalType = getLiteralType(primary);
|
|
49
|
+
const assertedType = assertionNode.typeName;
|
|
50
|
+
if (literalType === assertedType) {
|
|
51
|
+
const fix = this.fix?.(node, context) ?? null;
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
location: assertionNode.span.start,
|
|
55
|
+
severity: 'info',
|
|
56
|
+
code: 'UNNECESSARY_ASSERTION',
|
|
57
|
+
message: `Type assertion on ${literalType} literal is unnecessary`,
|
|
58
|
+
context: extractContextLine(assertionNode.span.start.line, context.source),
|
|
59
|
+
fix,
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
return [];
|
|
64
|
+
},
|
|
65
|
+
fix(node, context) {
|
|
66
|
+
const assertionNode = node;
|
|
67
|
+
const operand = assertionNode.operand;
|
|
68
|
+
if (!operand) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
// Find the end of the type assertion (:type part)
|
|
72
|
+
const assertionSource = context.source.substring(assertionNode.span.start.offset, assertionNode.span.end.offset);
|
|
73
|
+
// The type assertion is "literal:type" - we want to keep only "literal"
|
|
74
|
+
// Find the : character position
|
|
75
|
+
const colonIndex = assertionSource.indexOf(':');
|
|
76
|
+
if (colonIndex === -1) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// Calculate the actual end of ":type" part
|
|
80
|
+
const typeStart = assertionNode.span.start.offset + colonIndex;
|
|
81
|
+
const typeEnd = typeStart + 1 + assertionNode.typeName.length;
|
|
82
|
+
return {
|
|
83
|
+
description: 'Remove unnecessary type assertion',
|
|
84
|
+
applicable: true,
|
|
85
|
+
range: {
|
|
86
|
+
start: { ...assertionNode.span.start, offset: typeStart },
|
|
87
|
+
end: { ...assertionNode.span.start, offset: typeEnd },
|
|
88
|
+
},
|
|
89
|
+
replacement: '',
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Get the type name of a literal node.
|
|
95
|
+
*/
|
|
96
|
+
function getLiteralType(node) {
|
|
97
|
+
switch (node.type) {
|
|
98
|
+
case 'NumberLiteral':
|
|
99
|
+
return 'number';
|
|
100
|
+
case 'StringLiteral':
|
|
101
|
+
return 'string';
|
|
102
|
+
case 'BoolLiteral':
|
|
103
|
+
return 'bool';
|
|
104
|
+
case 'Tuple':
|
|
105
|
+
return 'list';
|
|
106
|
+
case 'Dict':
|
|
107
|
+
return 'dict';
|
|
108
|
+
default:
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// ============================================================
|
|
113
|
+
// VALIDATE_EXTERNAL RULE
|
|
114
|
+
// ============================================================
|
|
115
|
+
/**
|
|
116
|
+
* Recommends type assertions for external input validation.
|
|
117
|
+
* External inputs (from host functions, user input, parsed data) should be
|
|
118
|
+
* validated with type assertions to ensure type safety.
|
|
119
|
+
*
|
|
120
|
+
* Detection heuristics:
|
|
121
|
+
* - Host function calls (HostCall nodes)
|
|
122
|
+
* - Parsing functions (parse_json, parse_xml, etc.)
|
|
123
|
+
* - Variables from external sources ($ARGS, $ENV)
|
|
124
|
+
*
|
|
125
|
+
* This is an informational rule - not all external data needs assertions,
|
|
126
|
+
* but it's a good practice for critical paths.
|
|
127
|
+
*
|
|
128
|
+
* References:
|
|
129
|
+
* - docs/16_conventions.md:307-311
|
|
130
|
+
*/
|
|
131
|
+
export const VALIDATE_EXTERNAL = {
|
|
132
|
+
code: 'VALIDATE_EXTERNAL',
|
|
133
|
+
category: 'types',
|
|
134
|
+
severity: 'info',
|
|
135
|
+
nodeTypes: ['HostCall'],
|
|
136
|
+
validate(node, context) {
|
|
137
|
+
const hostCallNode = node;
|
|
138
|
+
const functionName = hostCallNode.name;
|
|
139
|
+
// Check if this is a parsing or external data function
|
|
140
|
+
const isExternalDataFunction = functionName.startsWith('parse_') ||
|
|
141
|
+
functionName.includes('fetch') ||
|
|
142
|
+
functionName.includes('read') ||
|
|
143
|
+
functionName.includes('load');
|
|
144
|
+
if (!isExternalDataFunction) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
// Check if the result is immediately asserted
|
|
148
|
+
// This would require checking the parent node context
|
|
149
|
+
// For now, we'll provide a general recommendation
|
|
150
|
+
return [
|
|
151
|
+
{
|
|
152
|
+
location: hostCallNode.span.start,
|
|
153
|
+
severity: 'info',
|
|
154
|
+
code: 'VALIDATE_EXTERNAL',
|
|
155
|
+
message: `Consider validating external input with type assertion: ${functionName}():type`,
|
|
156
|
+
context: extractContextLine(hostCallNode.span.start.line, context.source),
|
|
157
|
+
fix: null, // Cannot auto-fix - requires developer judgment
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/check/rules/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check Types
|
|
3
|
+
* Type definitions for the rill-check static analysis tool.
|
|
4
|
+
*/
|
|
5
|
+
import type { SourceLocation, SourceSpan, ScriptNode, NodeType, ASTNode } from '../types.js';
|
|
6
|
+
/** Diagnostic severity levels */
|
|
7
|
+
export type Severity = 'error' | 'warning' | 'info';
|
|
8
|
+
/** Rule state configuration */
|
|
9
|
+
export type RuleState = 'on' | 'off' | 'warn';
|
|
10
|
+
/**
|
|
11
|
+
* Fix suggestion for a diagnostic.
|
|
12
|
+
* Provides automated fix information that can be applied to source code.
|
|
13
|
+
*/
|
|
14
|
+
export interface Fix {
|
|
15
|
+
/** Human-readable description of what the fix does */
|
|
16
|
+
readonly description: string;
|
|
17
|
+
/** Whether the fix can be safely applied automatically */
|
|
18
|
+
readonly applicable: boolean;
|
|
19
|
+
/** Source range to replace */
|
|
20
|
+
readonly range: SourceSpan;
|
|
21
|
+
/** Replacement text */
|
|
22
|
+
readonly replacement: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A single diagnostic issue found during validation.
|
|
26
|
+
* Represents errors, warnings, or informational messages from static analysis.
|
|
27
|
+
*/
|
|
28
|
+
export interface Diagnostic {
|
|
29
|
+
/** Location of the issue in source */
|
|
30
|
+
readonly location: SourceLocation;
|
|
31
|
+
/** Severity level */
|
|
32
|
+
readonly severity: Severity;
|
|
33
|
+
/** Rule code (e.g., NAMING_SNAKE_CASE) */
|
|
34
|
+
readonly code: string;
|
|
35
|
+
/** Human-readable description */
|
|
36
|
+
readonly message: string;
|
|
37
|
+
/** Source line containing the issue */
|
|
38
|
+
readonly context: string;
|
|
39
|
+
/** Optional automatic fix */
|
|
40
|
+
readonly fix: Fix | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Configuration for check rules and severity overrides.
|
|
44
|
+
* Controls which rules are active and at what severity level.
|
|
45
|
+
*/
|
|
46
|
+
export interface CheckConfig {
|
|
47
|
+
/** Per-rule enable/disable/warn state */
|
|
48
|
+
readonly rules: Record<string, RuleState>;
|
|
49
|
+
/** Severity overrides by rule code */
|
|
50
|
+
readonly severity: Record<string, Severity>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Context for validation passes.
|
|
54
|
+
* Tracks source, AST, configuration, and accumulated diagnostics.
|
|
55
|
+
*/
|
|
56
|
+
export interface ValidationContext {
|
|
57
|
+
/** Original source text */
|
|
58
|
+
readonly source: string;
|
|
59
|
+
/** Parsed AST */
|
|
60
|
+
readonly ast: ScriptNode;
|
|
61
|
+
/** Active configuration */
|
|
62
|
+
readonly config: CheckConfig;
|
|
63
|
+
/** Accumulated diagnostics */
|
|
64
|
+
readonly diagnostics: Diagnostic[];
|
|
65
|
+
/** Variable definitions for collision detection */
|
|
66
|
+
readonly variables: Map<string, SourceLocation>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Context for fix generation.
|
|
70
|
+
* Provides access to source and AST for computing fix replacements.
|
|
71
|
+
*/
|
|
72
|
+
export interface FixContext {
|
|
73
|
+
/** Original source text */
|
|
74
|
+
readonly source: string;
|
|
75
|
+
/** Parsed AST */
|
|
76
|
+
readonly ast: ScriptNode;
|
|
77
|
+
}
|
|
78
|
+
/** Rule category for grouping and organization */
|
|
79
|
+
export type RuleCategory = 'naming' | 'flow' | 'collections' | 'loops' | 'conditionals' | 'closures' | 'types' | 'strings' | 'errors' | 'formatting' | 'anti-patterns';
|
|
80
|
+
/**
|
|
81
|
+
* Validation rule interface.
|
|
82
|
+
* Rules are stateless - all context passed via ValidationContext.
|
|
83
|
+
* Rules return diagnostics, never throw.
|
|
84
|
+
* fix() must preserve semantics (no behavior changes).
|
|
85
|
+
*/
|
|
86
|
+
export interface ValidationRule {
|
|
87
|
+
/** Unique rule code (e.g., NAMING_SNAKE_CASE) */
|
|
88
|
+
readonly code: string;
|
|
89
|
+
/** Rule category for grouping */
|
|
90
|
+
readonly category: RuleCategory;
|
|
91
|
+
/** Default severity level */
|
|
92
|
+
readonly severity: Severity;
|
|
93
|
+
/** Node types this rule applies to */
|
|
94
|
+
readonly nodeTypes: NodeType[];
|
|
95
|
+
/**
|
|
96
|
+
* Validate a node, returning diagnostics for violations.
|
|
97
|
+
* Called for each node matching nodeTypes.
|
|
98
|
+
*/
|
|
99
|
+
validate(node: ASTNode, context: ValidationContext): Diagnostic[];
|
|
100
|
+
/**
|
|
101
|
+
* Optionally generate a fix for a diagnostic.
|
|
102
|
+
* Returns null if fix not applicable.
|
|
103
|
+
*/
|
|
104
|
+
fix?(node: ASTNode, context: FixContext): Fix | null;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/check/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/check/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script Validator
|
|
3
|
+
* Orchestrates validation by traversing AST and invoking enabled rules.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScriptNode } from '../types.js';
|
|
6
|
+
import type { CheckConfig, Diagnostic } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Validate script AST against all enabled rules.
|
|
9
|
+
* Traverses AST using visitor pattern, invoking enabled rules for matching nodes.
|
|
10
|
+
* Returns diagnostics sorted by line number, then column.
|
|
11
|
+
*
|
|
12
|
+
* @param ast - Parsed script AST to validate
|
|
13
|
+
* @param source - Original source text for context extraction
|
|
14
|
+
* @param config - Configuration determining which rules are active
|
|
15
|
+
* @returns Array of diagnostics sorted by location
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateScript(ast: ScriptNode, source: string, config: CheckConfig): Diagnostic[];
|
|
18
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/check/validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAqB,MAAM,YAAY,CAAC;AAQ7E;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,UAAU,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,UAAU,EAAE,CAiDd"}
|