@scientific-method/standard-checker 2.1.0 → 2.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 +3 -1
- package/dist/checks/arguments.d.ts +17 -0
- package/dist/checks/arguments.js +195 -0
- package/dist/checks/fields.js +3 -4
- package/dist/checks/rules.d.ts +16 -0
- package/dist/checks/rules.js +32 -12
- package/dist/standard-checker.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,9 @@ A pass ends with `spec check passed:` and the counts of entries, parity rows and
|
|
|
20
20
|
step of the check did not run, it ends with `spec check passed with skipped steps:`, the counts, and
|
|
21
21
|
`Skipped:` followed by each step and why, such as
|
|
22
22
|
`Skipped: Kaitai compilation of 2 definitions (--no-ksy).` A failing run lists the skipped steps
|
|
23
|
-
after its problems.
|
|
23
|
+
after its problems. A `call` or `emit` whose arguments cannot be counted, because the Parameters
|
|
24
|
+
section it is counted against is missing or is not `None.` or a list of parameters, or because its
|
|
25
|
+
argument list is never closed, is a skipped step as well.
|
|
24
26
|
|
|
25
27
|
Without `--base`, the checker compares the spec with where HEAD forked from `origin/$GITHUB_BASE_REF`,
|
|
26
28
|
or from `origin/main` when that variable is unset. Outside a git repository, in a shallow clone, or
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Context } from "../context.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The number of parameters a rule's Parameters section lists: 0 for `None.`, otherwise the number
|
|
4
|
+
* of items of a Markdown list whose items each open with a code span holding a name, or a name, a
|
|
5
|
+
* colon and a type, followed directly by a colon (`` - `gang: FMT-DATA-005`: the gang ``). An item
|
|
6
|
+
* may continue on indented lines. Null when the section holds anything else, so its parameters
|
|
7
|
+
* cannot be counted: `None known.`, prose after the list, or an item that names two parameters
|
|
8
|
+
* (`` - `x`, `y`: the cell ``) or puts anything between its code span and the colon.
|
|
9
|
+
*/
|
|
10
|
+
export declare function parameterCount(section: string): number | null;
|
|
11
|
+
/**
|
|
12
|
+
* The number of arguments in the parenthesised list that opens at code[open], counting the commas
|
|
13
|
+
* outside nested brackets. Null when the list is not closed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function argumentCount(code: string, open: number): number | null;
|
|
16
|
+
/** Checks the argument count of every call, function call and emit in a live rule's procedure. */
|
|
17
|
+
export declare function checkArgumentCounts(ctx: Context): void;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// Argument counts: every `call` passes one argument for each item of the called rule's Parameters
|
|
2
|
+
// list, every call to a function a rule defines one for each parameter of its `define`, and every
|
|
3
|
+
// `emit` one for each item of the Parameters list of each handler its glossary entry names. Two
|
|
4
|
+
// `emit`s of one event in rules that share a build pass the same number of arguments, which is the
|
|
5
|
+
// only check an event with no handlers gets.
|
|
6
|
+
//
|
|
7
|
+
// A call to a split rule, and an emit to a split handler, is counted against each entry of the
|
|
8
|
+
// split that lists one of the calling or emitting rule's builds, and a call to a function that a
|
|
9
|
+
// split rule defines against the `define` of each such entry. A Parameters section in any other
|
|
10
|
+
// form than `None.` or the list gives no count, so the calls and emits that depend on it are named
|
|
11
|
+
// as a skipped step and do not fail the check. A call or emit whose argument list is never closed
|
|
12
|
+
// is named as a skipped step too. Only live rules are checked, and only live rules' `define`s are
|
|
13
|
+
// counted against.
|
|
14
|
+
import { asList, idsIn, kindOf } from "../ids.js";
|
|
15
|
+
import { BUILTINS, defines, procedureLocals, withoutCommentsAndStrings } from "./rules.js";
|
|
16
|
+
/**
|
|
17
|
+
* The number of parameters a rule's Parameters section lists: 0 for `None.`, otherwise the number
|
|
18
|
+
* of items of a Markdown list whose items each open with a code span holding a name, or a name, a
|
|
19
|
+
* colon and a type, followed directly by a colon (`` - `gang: FMT-DATA-005`: the gang ``). An item
|
|
20
|
+
* may continue on indented lines. Null when the section holds anything else, so its parameters
|
|
21
|
+
* cannot be counted: `None known.`, prose after the list, or an item that names two parameters
|
|
22
|
+
* (`` - `x`, `y`: the cell ``) or puts anything between its code span and the colon.
|
|
23
|
+
*/
|
|
24
|
+
export function parameterCount(section) {
|
|
25
|
+
const text = section.trim();
|
|
26
|
+
if (text === "None.")
|
|
27
|
+
return 0;
|
|
28
|
+
let count = 0;
|
|
29
|
+
for (const line of text.split("\n")) {
|
|
30
|
+
if (line.trim() === "")
|
|
31
|
+
continue;
|
|
32
|
+
if (/^[-*+]\s/.test(line)) {
|
|
33
|
+
if (!/^[-*+]\s+`[a-z_][a-z0-9_]*(?:\s*:\s*[^`\s][^`]*)?`:/.test(line))
|
|
34
|
+
return null;
|
|
35
|
+
count++;
|
|
36
|
+
}
|
|
37
|
+
else if (!(count > 0 && /^\s/.test(line)))
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return count > 0 ? count : null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The number of arguments in the parenthesised list that opens at code[open], counting the commas
|
|
44
|
+
* outside nested brackets. Null when the list is not closed.
|
|
45
|
+
*/
|
|
46
|
+
export function argumentCount(code, open) {
|
|
47
|
+
let depth = 0;
|
|
48
|
+
let commas = 0;
|
|
49
|
+
let empty = true;
|
|
50
|
+
for (let i = open + 1; i < code.length; i++) {
|
|
51
|
+
const c = code[i];
|
|
52
|
+
if (c === "(" || c === "[" || c === "{")
|
|
53
|
+
depth++;
|
|
54
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
55
|
+
if (depth === 0)
|
|
56
|
+
return empty ? 0 : commas + 1;
|
|
57
|
+
depth--;
|
|
58
|
+
}
|
|
59
|
+
else if (c === "," && depth === 0)
|
|
60
|
+
commas++;
|
|
61
|
+
if (!/\s/.test(c))
|
|
62
|
+
empty = false;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
// The argument count of a call or emit whose name ends at end: 0 when no list follows the name.
|
|
67
|
+
const countAfter = (code, end) => {
|
|
68
|
+
const opening = /[ \t]*\(/y;
|
|
69
|
+
opening.lastIndex = end;
|
|
70
|
+
return opening.test(code) ? argumentCount(code, opening.lastIndex - 1) : 0;
|
|
71
|
+
};
|
|
72
|
+
const plural = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
|
|
73
|
+
/** Checks the argument count of every call, function call and emit in a live rule's procedure. */
|
|
74
|
+
export function checkArgumentCounts(ctx) {
|
|
75
|
+
const { problem, skip } = ctx;
|
|
76
|
+
const { entries, glossary } = ctx.spec;
|
|
77
|
+
const live = [...entries].filter(([, e]) => e.kind === "RULE" && e.meta.status !== "superseded");
|
|
78
|
+
const builds = (e) => asList(e.meta.builds);
|
|
79
|
+
const sharesBuild = (a, b) => builds(a).some((x) => builds(b).includes(x));
|
|
80
|
+
const parametersOf = (id) => entries.get(id).sections.find((s) => s.title === "Parameters")?.text;
|
|
81
|
+
const counts = new Map();
|
|
82
|
+
const countOf = (id) => {
|
|
83
|
+
if (!counts.has(id))
|
|
84
|
+
counts.set(id, parameterCount(parametersOf(id) ?? ""));
|
|
85
|
+
return counts.get(id);
|
|
86
|
+
};
|
|
87
|
+
// The entries whose Parameters section a call to rule from caller is counted against: each entry
|
|
88
|
+
// of rule's split that lists one of the caller's builds, or rule itself when none does.
|
|
89
|
+
const targetsOf = (rule, caller) => {
|
|
90
|
+
const group = [rule, ...asList(entries.get(rule).meta.split_with)].filter((x) => entries.get(x)?.kind === "RULE");
|
|
91
|
+
const sharing = [...new Set(group)].filter((x) => sharesBuild(entries.get(x), caller));
|
|
92
|
+
return sharing.length ? sharing : [rule];
|
|
93
|
+
};
|
|
94
|
+
// Rule ID -> what could not be counted against its Parameters section -> how many times.
|
|
95
|
+
const uncounted = new Map();
|
|
96
|
+
const cannotCount = (target, what) => {
|
|
97
|
+
if (!uncounted.has(target))
|
|
98
|
+
uncounted.set(target, new Map());
|
|
99
|
+
const m = uncounted.get(target);
|
|
100
|
+
m.set(what, (m.get(what) ?? 0) + 1);
|
|
101
|
+
};
|
|
102
|
+
// What could not be counted because its argument list is never closed.
|
|
103
|
+
const unclosed = [];
|
|
104
|
+
// Function name -> the rules that define it, with the parameter count of each define.
|
|
105
|
+
const defined = new Map();
|
|
106
|
+
for (const [id, e] of live)
|
|
107
|
+
for (const { name, params } of defines(withoutCommentsAndStrings(e.code ?? ""))) {
|
|
108
|
+
if (!defined.has(name))
|
|
109
|
+
defined.set(name, []);
|
|
110
|
+
defined.get(name).push({ id, count: params.length });
|
|
111
|
+
}
|
|
112
|
+
// Event name -> the argument counts its emits pass, with the rule each comes from.
|
|
113
|
+
const emitted = new Map();
|
|
114
|
+
for (const [id, e] of live) {
|
|
115
|
+
const { file } = e;
|
|
116
|
+
const code = withoutCommentsAndStrings(e.code ?? "");
|
|
117
|
+
for (const m of code.matchAll(/\bcall\s+(RULE-[A-Z0-9]+-\d+)/g)) {
|
|
118
|
+
const called = entries.get(m[1]);
|
|
119
|
+
if (!called || called.kind !== "RULE")
|
|
120
|
+
continue;
|
|
121
|
+
const n = countAfter(code, m.index + m[0].length);
|
|
122
|
+
if (n === null) {
|
|
123
|
+
unclosed.push(`call of ${m[1]} in ${id}`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
for (const target of targetsOf(m[1], e)) {
|
|
127
|
+
const want = countOf(target);
|
|
128
|
+
if (want === null)
|
|
129
|
+
cannotCount(target, `call in ${id}`);
|
|
130
|
+
else if (want !== n)
|
|
131
|
+
problem(file, target === m[1]
|
|
132
|
+
? `calls ${m[1]} with ${plural(n, "argument")}, but its Parameters section lists ${plural(want, "parameter")}`
|
|
133
|
+
: `calls ${m[1]} with ${plural(n, "argument")}, but the Parameters section of ${target}, the entry of the split that lists a build of this rule, lists ${plural(want, "parameter")}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// A name the procedure declares itself, or a built-in, is not a function another rule defines.
|
|
137
|
+
const locals = procedureLocals(code, parametersOf(id) ?? "");
|
|
138
|
+
for (const m of code.matchAll(/(?<![.\w])(?<!\b(?:define|emit)\s+)([a-z_][a-z0-9_]*)\s*\(/g)) {
|
|
139
|
+
const owners = defined.get(m[1]);
|
|
140
|
+
if (!owners || locals.has(m[1]) || BUILTINS.has(m[1]))
|
|
141
|
+
continue;
|
|
142
|
+
const n = argumentCount(code, m.index + m[0].length - 1);
|
|
143
|
+
if (n === null) {
|
|
144
|
+
unclosed.push(`call of ${m[1]}() in ${id}`);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const near = owners.filter((o) => o.id === id || sharesBuild(entries.get(o.id), e));
|
|
148
|
+
if (near.length) {
|
|
149
|
+
for (const { id: owner, count } of near)
|
|
150
|
+
if (count !== n)
|
|
151
|
+
problem(file, `calls ${m[1]}() with ${plural(n, "argument")}, but its define in ${owner} takes ${plural(count, "parameter")}`);
|
|
152
|
+
}
|
|
153
|
+
else if (owners.every((o) => o.count !== n))
|
|
154
|
+
// No define lists one of this rule's builds, so the call is wrong only if it fits none of them.
|
|
155
|
+
problem(file, owners.length === 1
|
|
156
|
+
? `calls ${m[1]}() with ${plural(n, "argument")}, but its define in ${owners[0].id} takes ${plural(owners[0].count, "parameter")}`
|
|
157
|
+
: `calls ${m[1]}() with ${plural(n, "argument")}, but none of its defines takes that many (${owners.map((o) => `${plural(o.count, "parameter")} in ${o.id}`).join(", ")})`);
|
|
158
|
+
}
|
|
159
|
+
for (const m of code.matchAll(/\bemit\s+([A-Za-z_][A-Za-z0-9_]*)/g)) {
|
|
160
|
+
const event = m[1];
|
|
161
|
+
const n = countAfter(code, m.index + m[0].length);
|
|
162
|
+
if (n === null) {
|
|
163
|
+
unclosed.push(`emit of ${event} in ${id}`);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (!emitted.has(event))
|
|
167
|
+
emitted.set(event, []);
|
|
168
|
+
const others = emitted.get(event);
|
|
169
|
+
const other = others.find((o) => o.count !== n && (o.id === id || sharesBuild(o.entry, e)));
|
|
170
|
+
if (other)
|
|
171
|
+
problem(file, other.id === id
|
|
172
|
+
? `emits ${event} with ${plural(n, "argument")}, but also emits it with ${plural(other.count, "argument")}`
|
|
173
|
+
: `emits ${event} with ${plural(n, "argument")}, but ${other.id} emits it with ${plural(other.count, "argument")}`);
|
|
174
|
+
if (!others.some((o) => o.id === id && o.count === n))
|
|
175
|
+
others.push({ id, entry: e, count: n });
|
|
176
|
+
const handlers = idsIn(glossary.get(event)).filter((x) => kindOf(x) === "RULE" && entries.get(x)?.kind === "RULE");
|
|
177
|
+
for (const handler of new Set(handlers.flatMap((h) => targetsOf(h, e)))) {
|
|
178
|
+
const want = countOf(handler);
|
|
179
|
+
if (want === null)
|
|
180
|
+
cannotCount(handler, `emit of ${event} in ${id}`);
|
|
181
|
+
else if (want !== n)
|
|
182
|
+
problem(file, `emits ${event} with ${plural(n, "argument")}, but the Parameters section of its handler ${handler} lists ${plural(want, "parameter")}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
for (const [target, whats] of uncounted) {
|
|
187
|
+
const list = [...whats].map(([what, times]) => (times > 1 ? `${what} (${times} times)` : what)).join(", ");
|
|
188
|
+
const why = parametersOf(target) === undefined
|
|
189
|
+
? "which has no Parameters section"
|
|
190
|
+
: "whose Parameters section is not None. or a list of parameters";
|
|
191
|
+
skip(`argument counts against ${target}, ${why} (${list})`);
|
|
192
|
+
}
|
|
193
|
+
for (const what of new Set(unclosed))
|
|
194
|
+
skip(`the argument count of the ${what}, whose argument list is not closed`);
|
|
195
|
+
}
|
package/dist/checks/fields.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// unchecked. A declaration that writes no type, such as a parameter the Parameters section describes
|
|
22
22
|
// in prose or an untyped parameter of a define, gives none and so differs from no other.
|
|
23
23
|
import { asList } from "../ids.js";
|
|
24
|
-
import { parameterNames, withoutCommentsAndStrings } from "./rules.js";
|
|
24
|
+
import { defines, parameterNames, withoutCommentsAndStrings } from "./rules.js";
|
|
25
25
|
const sameType = (a, b) => !!a && !!b && a.format.join(" ") === b.format.join(" ") && a.pointer === b.pointer && a.list === b.list;
|
|
26
26
|
const FMT_ID = String.raw `FMT-[A-Z][A-Z0-9]*-\d{3,}`;
|
|
27
27
|
// A type in the notation that holds a structure: a format ID, a pointer to one, or a list of either.
|
|
@@ -184,9 +184,8 @@ export function checkFieldNames(ctx, { layouts }) {
|
|
|
184
184
|
for (const name of parameterNames(params))
|
|
185
185
|
declare(name, fixed(typedParams.has(name) ? typedParams.get(name) : undefined, "the Parameters section"));
|
|
186
186
|
for (const line of lines) {
|
|
187
|
-
const d
|
|
188
|
-
|
|
189
|
-
for (const p of d[1].split(",")) {
|
|
187
|
+
for (const d of defines(line))
|
|
188
|
+
for (const p of d.params) {
|
|
190
189
|
const [name, type] = p.split(":");
|
|
191
190
|
if (/^[a-z_][a-z0-9_]*$/.test(name.trim()))
|
|
192
191
|
declare(name.trim(), fixed(type === undefined ? undefined : typeOf(type), "its define"));
|
package/dist/checks/rules.d.ts
CHANGED
|
@@ -7,5 +7,21 @@ import type { FormatNames } from "./formats.ts";
|
|
|
7
7
|
export declare const withoutCommentsAndStrings: (code: string) => string;
|
|
8
8
|
/** The names a rule's Parameters section declares: each lower-case name that opens a code span, as `n` or `n: type`. */
|
|
9
9
|
export declare const parameterNames: (params: string) => string[];
|
|
10
|
+
/**
|
|
11
|
+
* Each `define` in a procedure: the function's name and its parameters as written, with their types
|
|
12
|
+
* (`n: UINT16`). A define with no parameters has an empty list.
|
|
13
|
+
*/
|
|
14
|
+
export declare const defines: (code: string) => {
|
|
15
|
+
name: string;
|
|
16
|
+
params: string[];
|
|
17
|
+
}[];
|
|
18
|
+
/**
|
|
19
|
+
* The names a procedure declares for itself: its `let`s, its loop variables, the parameters of its
|
|
20
|
+
* `define`s and the names its rule's Parameters section lists. A call to one of these names calls
|
|
21
|
+
* the local value, not a function another rule defines.
|
|
22
|
+
*/
|
|
23
|
+
export declare function procedureLocals(code: string, params: string): Set<string>;
|
|
24
|
+
/** The functions every procedure may call without a rule defining them. */
|
|
25
|
+
export declare const BUILTINS: Set<string>;
|
|
10
26
|
/** Checks every rule's procedure. Sets Entry.code on every rule entry, superseded ones included. */
|
|
11
27
|
export declare function checkRules(ctx: Context, { enumNames }: FormatNames): void;
|
package/dist/checks/rules.js
CHANGED
|
@@ -13,7 +13,37 @@ import { KINDS, LIST_LIMIT } from "../standard.js";
|
|
|
13
13
|
export const withoutCommentsAndStrings = (code) => code.replace(/"[^"\n]*"/g, '""').replace(/#.*$/gm, "");
|
|
14
14
|
/** The names a rule's Parameters section declares: each lower-case name that opens a code span, as `n` or `n: type`. */
|
|
15
15
|
export const parameterNames = (params) => [...params.matchAll(/`([a-z_][a-z0-9_]*)(?=`|\s*:)/g)].map((m) => m[1]);
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Each `define` in a procedure: the function's name and its parameters as written, with their types
|
|
18
|
+
* (`n: UINT16`). A define with no parameters has an empty list.
|
|
19
|
+
*/
|
|
20
|
+
export const defines = (code) => [...code.matchAll(/\bdefine\s+([a-z_][a-z0-9_]*)\s*\(([^)]*)\)/g)].map((m) => ({
|
|
21
|
+
name: m[1],
|
|
22
|
+
params: m[2]
|
|
23
|
+
.split(",")
|
|
24
|
+
.map((p) => p.trim())
|
|
25
|
+
.filter((p) => p !== ""),
|
|
26
|
+
}));
|
|
27
|
+
/**
|
|
28
|
+
* The names a procedure declares for itself: its `let`s, its loop variables, the parameters of its
|
|
29
|
+
* `define`s and the names its rule's Parameters section lists. A call to one of these names calls
|
|
30
|
+
* the local value, not a function another rule defines.
|
|
31
|
+
*/
|
|
32
|
+
export function procedureLocals(code, params) {
|
|
33
|
+
const locals = new Set();
|
|
34
|
+
for (const m of code.matchAll(/\blet\s+([a-z_][a-z0-9_]*)/g))
|
|
35
|
+
locals.add(m[1]);
|
|
36
|
+
for (const m of code.matchAll(/\bfor\s+(?:each\s+)?([a-z_][a-z0-9_]*)\s+in\b/g))
|
|
37
|
+
locals.add(m[1]);
|
|
38
|
+
for (const d of defines(code))
|
|
39
|
+
for (const p of d.params)
|
|
40
|
+
locals.add(p.split(":")[0].trim());
|
|
41
|
+
for (const name of parameterNames(params))
|
|
42
|
+
locals.add(name);
|
|
43
|
+
return locals;
|
|
44
|
+
}
|
|
45
|
+
/** The functions every procedure may call without a rule defining them. */
|
|
46
|
+
export const BUILTINS = new Set([
|
|
17
47
|
"min",
|
|
18
48
|
"max",
|
|
19
49
|
"abs",
|
|
@@ -191,17 +221,7 @@ export function checkRules(ctx, { enumNames }) {
|
|
|
191
221
|
if (/\b0x[0-9A-Fa-f]{6,}\b/.test(noNeutral) && /\b0x00[4-9A-F][0-9A-F]{5}\b/.test(noNeutral))
|
|
192
222
|
problem(file, "the procedure contains what looks like an address outside a neutral name");
|
|
193
223
|
// Functions called without `call`
|
|
194
|
-
const locals =
|
|
195
|
-
for (const m of code.matchAll(/\blet\s+([a-z_][a-z0-9_]*)/g))
|
|
196
|
-
locals.add(m[1]);
|
|
197
|
-
for (const m of code.matchAll(/\bfor\s+(?:each\s+)?([a-z_][a-z0-9_]*)\s+in\b/g))
|
|
198
|
-
locals.add(m[1]);
|
|
199
|
-
for (const m of code.matchAll(/\bdefine\s+[a-z_][a-z0-9_]*\s*\(([^)]*)\)/g))
|
|
200
|
-
for (const p of m[1].split(","))
|
|
201
|
-
locals.add(p.split(":")[0].trim());
|
|
202
|
-
const params = e.sections.find((s) => s.title === "Parameters")?.text ?? "";
|
|
203
|
-
for (const name of parameterNames(params))
|
|
204
|
-
locals.add(name);
|
|
224
|
+
const locals = procedureLocals(code, e.sections.find((s) => s.title === "Parameters")?.text ?? "");
|
|
205
225
|
for (const m of code.matchAll(/(?<![.\w])([a-z_][a-z0-9_]*)\s*\(/g)) {
|
|
206
226
|
const name = m[1];
|
|
207
227
|
if (BUILTINS.has(name) || KEYWORDS.has(name) || locals.has(name))
|
package/dist/standard-checker.js
CHANGED
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
import { readFileSync } from "node:fs";
|
|
63
63
|
import { dirname } from "node:path";
|
|
64
64
|
import { fileURLToPath } from "node:url";
|
|
65
|
+
import { checkArgumentCounts } from "./checks/arguments.js";
|
|
65
66
|
import { checkBase } from "./checks/base.js";
|
|
66
67
|
import { checkCommentAddresses } from "./checks/comment-addresses.js";
|
|
67
68
|
import { checkAcrossEntries } from "./checks/cross-entry.js";
|
|
@@ -98,6 +99,7 @@ const spec = loadSpec({ config, problem });
|
|
|
98
99
|
const ctx = { config, problem, skip, spec, codeFiles: createCodeFiles(config, dirname(selfPath)) };
|
|
99
100
|
const formatNames = checkEntries(ctx);
|
|
100
101
|
checkRules(ctx, formatNames);
|
|
102
|
+
checkArgumentCounts(ctx);
|
|
101
103
|
checkFieldNames(ctx, formatNames);
|
|
102
104
|
checkAcrossEntries(ctx, formatNames);
|
|
103
105
|
compileKaitai(ctx);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scientific-method/standard-checker",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Checks a restoration's spec/, parity/ and deviations/ against version 1 of the dinorefurb documentation standard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|