@nielspeter/eess-ts 0.5.1 → 0.7.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 +2 -2
- package/dist/builders/class-rule-builder.d.ts +6 -10
- package/dist/builders/class-rule-builder.d.ts.map +1 -1
- package/dist/builders/class-rule-builder.js +33 -4
- package/dist/builders/class-rule-builder.js.map +1 -1
- package/dist/builders/function-rule-builder.d.ts +29 -7
- package/dist/builders/function-rule-builder.d.ts.map +1 -1
- package/dist/builders/function-rule-builder.js +34 -8
- package/dist/builders/function-rule-builder.js.map +1 -1
- package/dist/conditions/body-analysis-function.d.ts.map +1 -1
- package/dist/conditions/body-analysis-function.js +19 -1
- package/dist/conditions/body-analysis-function.js.map +1 -1
- package/dist/conditions/body-analysis-module.d.ts.map +1 -1
- package/dist/conditions/body-analysis-module.js +37 -4
- package/dist/conditions/body-analysis-module.js.map +1 -1
- package/dist/conditions/body-analysis.d.ts +5 -2
- package/dist/conditions/body-analysis.d.ts.map +1 -1
- package/dist/conditions/body-analysis.js +9 -6
- package/dist/conditions/body-analysis.js.map +1 -1
- package/dist/conditions/call.d.ts +8 -5
- package/dist/conditions/call.d.ts.map +1 -1
- package/dist/conditions/call.js +46 -20
- package/dist/conditions/call.js.map +1 -1
- package/dist/conditions/catch-analysis.d.ts +7 -1
- package/dist/conditions/catch-analysis.d.ts.map +1 -1
- package/dist/conditions/catch-analysis.js +26 -27
- package/dist/conditions/catch-analysis.js.map +1 -1
- package/dist/conditions/class.d.ts +5 -3
- package/dist/conditions/class.d.ts.map +1 -1
- package/dist/conditions/class.js +9 -6
- package/dist/conditions/class.js.map +1 -1
- package/dist/conditions/function.d.ts +4 -4
- package/dist/conditions/function.js +4 -4
- package/dist/core/execute-rule.js +1 -1
- package/dist/core/object-literal-functions.d.ts +4 -1
- package/dist/core/object-literal-functions.d.ts.map +1 -1
- package/dist/core/object-literal-functions.js +27 -5
- package/dist/core/object-literal-functions.js.map +1 -1
- package/dist/core/through-wrappers.d.ts +24 -0
- package/dist/core/through-wrappers.d.ts.map +1 -0
- package/dist/core/through-wrappers.js +36 -0
- package/dist/core/through-wrappers.js.map +1 -0
- package/dist/core/vacuity-diagnosis.d.ts.map +1 -1
- package/dist/core/vacuity-diagnosis.js +11 -3
- package/dist/core/vacuity-diagnosis.js.map +1 -1
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
- package/dist/graphql/resolver-rule-builder.js +16 -2
- package/dist/graphql/resolver-rule-builder.js.map +1 -1
- package/dist/helpers/body-traversal.d.ts +74 -20
- package/dist/helpers/body-traversal.d.ts.map +1 -1
- package/dist/helpers/body-traversal.js +273 -48
- package/dist/helpers/body-traversal.js.map +1 -1
- package/dist/helpers/callback-extractor.d.ts +6 -1
- package/dist/helpers/callback-extractor.d.ts.map +1 -1
- package/dist/helpers/callback-extractor.js +45 -10
- package/dist/helpers/callback-extractor.js.map +1 -1
- package/dist/helpers/global-binding.d.ts +11 -0
- package/dist/helpers/global-binding.d.ts.map +1 -0
- package/dist/helpers/global-binding.js +232 -0
- package/dist/helpers/global-binding.js.map +1 -0
- package/dist/helpers/heritage.d.ts +25 -0
- package/dist/helpers/heritage.d.ts.map +1 -0
- package/dist/helpers/heritage.js +41 -0
- package/dist/helpers/heritage.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/models/arch-function.d.ts +44 -14
- package/dist/models/arch-function.d.ts.map +1 -1
- package/dist/models/arch-function.js +226 -43
- package/dist/models/arch-function.js.map +1 -1
- package/dist/predicates/class.d.ts +9 -9
- package/dist/predicates/class.d.ts.map +1 -1
- package/dist/predicates/class.js +14 -13
- package/dist/predicates/class.js.map +1 -1
- package/dist/predicates/function.d.ts +16 -4
- package/dist/predicates/function.d.ts.map +1 -1
- package/dist/predicates/function.js +56 -3
- package/dist/predicates/function.js.map +1 -1
- package/dist/predicates/type.d.ts +2 -1
- package/dist/predicates/type.d.ts.map +1 -1
- package/dist/predicates/type.js +6 -2
- package/dist/predicates/type.js.map +1 -1
- package/dist/presets/agent-guardrails.js +5 -5
- package/dist/presets/agent-guardrails.js.map +1 -1
- package/dist/presets/recommended.d.ts +14 -6
- package/dist/presets/recommended.d.ts.map +1 -1
- package/dist/presets/recommended.js +30 -11
- package/dist/presets/recommended.js.map +1 -1
- package/dist/rules/code-quality.d.ts +12 -1
- package/dist/rules/code-quality.d.ts.map +1 -1
- package/dist/rules/code-quality.js +106 -12
- package/dist/rules/code-quality.js.map +1 -1
- package/dist/rules/errors.d.ts +4 -2
- package/dist/rules/errors.d.ts.map +1 -1
- package/dist/rules/errors.js +44 -23
- package/dist/rules/errors.js.map +1 -1
- package/dist/rules/hygiene.d.ts +3 -1
- package/dist/rules/hygiene.d.ts.map +1 -1
- package/dist/rules/hygiene.js +3 -1
- package/dist/rules/hygiene.js.map +1 -1
- package/dist/rules/metrics.d.ts +6 -4
- package/dist/rules/metrics.d.ts.map +1 -1
- package/dist/rules/metrics.js +40 -20
- package/dist/rules/metrics.js.map +1 -1
- package/dist/rules/security.d.ts +19 -5
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +198 -19
- package/dist/rules/security.js.map +1 -1
- package/dist/rules/typescript.d.ts +2 -2
- package/dist/rules/typescript.js +2 -2
- package/dist/smells/duplicate-bodies.js +2 -2
- package/dist/smells/duplicate-bodies.js.map +1 -1
- package/dist/smells/sibling-files.js +2 -2
- package/dist/smells/sibling-files.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body-analysis.js","sourceRoot":"","sources":["../../src/conditions/body-analysis.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAE5E,uEAAuE;AAEvE
|
|
1
|
+
{"version":3,"file":"body-analysis.js","sourceRoot":"","sources":["../../src/conditions/body-analysis.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAE5E,uEAAuE;AAEvE;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAA0B;IACrD,OAAO;QACL,WAAW,EAAE,WAAW,OAAO,CAAC,WAAW,EAAE;QAC7C,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;gBAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,UAAU,CAAC,IAAI,CACb,eAAe,CACb,GAAG,EACH,GAAG,cAAc,CAAC,GAAG,CAAC,qBAAqB,OAAO,CAAC,WAAW,EAAE,EAChE,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,OAA0B;IACxD,OAAO;QACL,WAAW,EAAE,eAAe,OAAO,CAAC,WAAW,EAAE;QACjD,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;gBACxD,MAAM,UAAU,GAAG,eAAe,CAChC,YAAY,EACZ,GAAG,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,EACjC,MAAM,CAAC,aAAa,EACpB,OAAO,CAAC,WAAW,CACpB,CAAA;gBACD,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBAC3C,UAAU,CAAC,IAAI,CAAC;wBACd,GAAG,eAAe,CAChB,GAAG,EACH,GAAG,cAAc,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,WAAW,YAAY,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAC7H,OAAO,CACR;wBACD,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC;qBAC5B,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;YACJ,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAsB,EACtB,IAAuB;IAEvB,OAAO;QACL,WAAW,EAAE,OAAO,IAAI,CAAC,WAAW,eAAe,GAAG,CAAC,WAAW,EAAE;QACpE,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;gBACvD,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;gBAE5D,4CAA4C;gBAC5C,MAAM,UAAU,GAAG,eAAe,CAChC,YAAY,EACZ,GAAG,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,EACjC,SAAS,CAAC,aAAa,EACvB,GAAG,CAAC,WAAW,CAChB,CAAA;gBACD,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBAC9C,UAAU,CAAC,IAAI,CAAC;wBACd,GAAG,eAAe,CAChB,GAAG,EACH,GAAG,cAAc,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,WAAW,YAAY,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,WAAW,UAAU,EAC9J,OAAO,CACR;wBACD,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC;qBAC5B,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;gBAEF,2DAA2D;gBAC3D,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;oBACtB,UAAU,CAAC,IAAI,CACb,eAAe,CACb,GAAG,EACH,GAAG,cAAc,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,WAAW,EAAE,EAC7D,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,WAAW,EAAE,wBAAwB;QACrC,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAClC,UAAU,CAAC,IAAI,CACb,eAAe,CACb,GAAG,EACH,GAAG,cAAc,CAAC,GAAG,CAAC,mCAAmC,EACzD,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -8,14 +8,15 @@ export declare function notExist(): Condition<ArchCall>;
|
|
|
8
8
|
/**
|
|
9
9
|
* Assert that at least one callback argument contains a match.
|
|
10
10
|
*
|
|
11
|
-
* Searches
|
|
12
|
-
*
|
|
11
|
+
* Searches every callback the call passes — see {@link callbackBodies} — for a node matching the
|
|
12
|
+
* given ExpressionMatcher.
|
|
13
13
|
*/
|
|
14
14
|
export declare function haveCallbackContaining(matcher: ExpressionMatcher): Condition<ArchCall>;
|
|
15
15
|
/**
|
|
16
16
|
* Assert that NO callback argument contains a match.
|
|
17
17
|
*
|
|
18
|
-
* Produces one violation per matching node found in any callback
|
|
18
|
+
* Produces one violation per matching node found in any callback — see {@link callbackBodies} for
|
|
19
|
+
* which arguments hold one.
|
|
19
20
|
*/
|
|
20
21
|
export declare function notHaveCallbackContaining(matcher: ExpressionMatcher): Condition<ArchCall>;
|
|
21
22
|
/**
|
|
@@ -40,7 +41,8 @@ export declare function notHaveArgumentWithProperty(...names: string[]): Conditi
|
|
|
40
41
|
/**
|
|
41
42
|
* Assert that at least one argument subtree contains a match.
|
|
42
43
|
*
|
|
43
|
-
* Searches ALL arguments of each call recursively using `
|
|
44
|
+
* Searches ALL arguments of each call recursively using `findMatchesInCode`,
|
|
45
|
+
* which tests each argument itself too (bug 0323).
|
|
44
46
|
* This is a superset of `haveCallbackContaining` — it searches the entire
|
|
45
47
|
* subtree of every argument (object literals, callbacks, nested expressions),
|
|
46
48
|
* not just function-like arguments. Use `haveCallbackContaining` when you
|
|
@@ -50,7 +52,8 @@ export declare function haveArgumentContaining(matcher: ExpressionMatcher): Cond
|
|
|
50
52
|
/**
|
|
51
53
|
* Assert that NO argument subtree contains a match.
|
|
52
54
|
*
|
|
53
|
-
* Searches ALL arguments of each call recursively using `
|
|
55
|
+
* Searches ALL arguments of each call recursively using `findMatchesInCode`,
|
|
56
|
+
* which tests each argument itself too (bug 0323).
|
|
54
57
|
* Produces one violation per matching node found in any argument.
|
|
55
58
|
*
|
|
56
59
|
* This is a superset of `notHaveCallbackContaining` — it searches the entire
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/conditions/call.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/conditions/call.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAiDtD;;GAEG;AACH,wBAAgB,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,CAiB9C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC,CAoBtF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC,CAkCzF;AA6DD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAyChF;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAwCnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC,CA4BtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC,CA+BzF"}
|
package/dist/conditions/call.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ArchConfigError } from '@nielspeter/eess';
|
|
2
2
|
import { Node } from 'ts-morph';
|
|
3
|
-
import {
|
|
3
|
+
import { findMatchesInCode, findMatchesInEach, reportedLine } from '../helpers/body-traversal.js';
|
|
4
|
+
import { extractCallbacks } from '../helpers/callback-extractor.js';
|
|
4
5
|
import { identifyMatches } from './match-identity.js';
|
|
5
6
|
import { marksAssertsCardinality } from '@nielspeter/eess/internal';
|
|
6
7
|
/**
|
|
@@ -57,8 +58,8 @@ export function notExist() {
|
|
|
57
58
|
/**
|
|
58
59
|
* Assert that at least one callback argument contains a match.
|
|
59
60
|
*
|
|
60
|
-
* Searches
|
|
61
|
-
*
|
|
61
|
+
* Searches every callback the call passes — see {@link callbackBodies} — for a node matching the
|
|
62
|
+
* given ExpressionMatcher.
|
|
62
63
|
*/
|
|
63
64
|
export function haveCallbackContaining(matcher) {
|
|
64
65
|
return {
|
|
@@ -78,7 +79,8 @@ export function haveCallbackContaining(matcher) {
|
|
|
78
79
|
/**
|
|
79
80
|
* Assert that NO callback argument contains a match.
|
|
80
81
|
*
|
|
81
|
-
* Produces one violation per matching node found in any callback
|
|
82
|
+
* Produces one violation per matching node found in any callback — see {@link callbackBodies} for
|
|
83
|
+
* which arguments hold one.
|
|
82
84
|
*/
|
|
83
85
|
export function notHaveCallbackContaining(matcher) {
|
|
84
86
|
return {
|
|
@@ -90,14 +92,10 @@ export function notHaveCallbackContaining(matcher) {
|
|
|
90
92
|
// produces multiple violations against the same call, and the
|
|
91
93
|
// literal-shape walk inside getName({...}) is identical for each.
|
|
92
94
|
const callName = callNameForMessage(archCall, context);
|
|
93
|
-
const args = archCall.getArguments();
|
|
94
95
|
// Flatten across arguments before assigning identities: a per-argument
|
|
95
96
|
// counter would restart at 1 for each callback, so two callbacks with a
|
|
96
97
|
// match in the same enclosing declaration would collide.
|
|
97
|
-
const matches =
|
|
98
|
-
const body = getFunctionBody(arg);
|
|
99
|
-
return body ? findMatchesInNode(body, matcher) : [];
|
|
100
|
-
});
|
|
98
|
+
const matches = findMatchesInEach(callbackBodies(archCall), matcher);
|
|
101
99
|
const identities = identifyMatches('call-callback', archCall.getSourceFile().getFilePath(), matches.map((m) => m.node), `${identityNameOf(archCall, context)} :: ${matcher.description}`);
|
|
102
100
|
matches.forEach((match, index) => {
|
|
103
101
|
violations.push({
|
|
@@ -110,17 +108,43 @@ export function notHaveCallbackContaining(matcher) {
|
|
|
110
108
|
},
|
|
111
109
|
};
|
|
112
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* The bodies the callback conditions search: every callback the call passes, as `extractCallbacks`
|
|
113
|
+
* reads them — the definition `within()` already used (bug 0324).
|
|
114
|
+
*
|
|
115
|
+
* Before this fix these conditions had their own, narrower one: an argument that IS an arrow
|
|
116
|
+
* function or a function expression. A handler in an options object — `use({ handler: () => … })`,
|
|
117
|
+
* the shape the builder's own example is written for — and one behind parentheses were searched by
|
|
118
|
+
* nothing, so `notHaveCallbackContaining` passed over them while `notHaveArgumentContaining`
|
|
119
|
+
* reported them. Two places deciding what a callback is, is the bug; there is now one.
|
|
120
|
+
*
|
|
121
|
+
* **The callbacks read before this fix come first.** A match's identity is numbered within its
|
|
122
|
+
* enclosing declaration, so a newly reachable callback on an earlier argument would otherwise take
|
|
123
|
+
* the ordinal a baseline accepted on a later one — the same ordering `findMatchesInEach` keeps for
|
|
124
|
+
* the roots bug 0323 made it test, and `searchClassBody` for the code bugs 0300, 0307 and 0309
|
|
125
|
+
* made it read.
|
|
126
|
+
*/
|
|
127
|
+
function callbackBodies(archCall) {
|
|
128
|
+
const args = archCall.getArguments();
|
|
129
|
+
const callbacks = extractCallbacks(archCall.getNode());
|
|
130
|
+
// A callback that IS the argument is what these conditions searched before bug 0324, when they read an
|
|
131
|
+
// argument's body themselves.
|
|
132
|
+
const wasRead = (fn) => args.some((arg) => arg === fn);
|
|
133
|
+
const ordered = [
|
|
134
|
+
...callbacks.filter((cb) => wasRead(cb.fn.getNode())),
|
|
135
|
+
...callbacks.filter((cb) => !wasRead(cb.fn.getNode())),
|
|
136
|
+
];
|
|
137
|
+
return ordered.flatMap((cb) => {
|
|
138
|
+
const body = cb.fn.getBody();
|
|
139
|
+
return body ? [body] : [];
|
|
140
|
+
});
|
|
141
|
+
}
|
|
113
142
|
/**
|
|
114
143
|
* Search all callback arguments of a call for a matcher hit.
|
|
115
144
|
*/
|
|
116
145
|
function searchCallbacksFor(archCall, matcher) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
const body = getFunctionBody(arg);
|
|
120
|
-
if (!body)
|
|
121
|
-
continue;
|
|
122
|
-
const matches = findMatchesInNode(body, matcher);
|
|
123
|
-
if (matches.length > 0)
|
|
146
|
+
for (const body of callbackBodies(archCall)) {
|
|
147
|
+
if (findMatchesInCode(body, matcher).length > 0)
|
|
124
148
|
return true;
|
|
125
149
|
}
|
|
126
150
|
return false;
|
|
@@ -223,7 +247,8 @@ export function notHaveArgumentWithProperty(...names) {
|
|
|
223
247
|
/**
|
|
224
248
|
* Assert that at least one argument subtree contains a match.
|
|
225
249
|
*
|
|
226
|
-
* Searches ALL arguments of each call recursively using `
|
|
250
|
+
* Searches ALL arguments of each call recursively using `findMatchesInCode`,
|
|
251
|
+
* which tests each argument itself too (bug 0323).
|
|
227
252
|
* This is a superset of `haveCallbackContaining` — it searches the entire
|
|
228
253
|
* subtree of every argument (object literals, callbacks, nested expressions),
|
|
229
254
|
* not just function-like arguments. Use `haveCallbackContaining` when you
|
|
@@ -238,7 +263,7 @@ export function haveArgumentContaining(matcher) {
|
|
|
238
263
|
const args = archCall.getArguments();
|
|
239
264
|
let found = false;
|
|
240
265
|
for (const arg of args) {
|
|
241
|
-
const matches =
|
|
266
|
+
const matches = findMatchesInCode(arg, matcher);
|
|
242
267
|
if (matches.length > 0) {
|
|
243
268
|
found = true;
|
|
244
269
|
break;
|
|
@@ -255,7 +280,8 @@ export function haveArgumentContaining(matcher) {
|
|
|
255
280
|
/**
|
|
256
281
|
* Assert that NO argument subtree contains a match.
|
|
257
282
|
*
|
|
258
|
-
* Searches ALL arguments of each call recursively using `
|
|
283
|
+
* Searches ALL arguments of each call recursively using `findMatchesInCode`,
|
|
284
|
+
* which tests each argument itself too (bug 0323).
|
|
259
285
|
* Produces one violation per matching node found in any argument.
|
|
260
286
|
*
|
|
261
287
|
* This is a superset of `notHaveCallbackContaining` — it searches the entire
|
|
@@ -273,7 +299,7 @@ export function notHaveArgumentContaining(matcher) {
|
|
|
273
299
|
// same archCall — same identity work each time.
|
|
274
300
|
const callName = callNameForMessage(archCall, context);
|
|
275
301
|
const args = archCall.getArguments();
|
|
276
|
-
const matches = args
|
|
302
|
+
const matches = findMatchesInEach(args, matcher);
|
|
277
303
|
const identities = identifyMatches('call-argument', archCall.getSourceFile().getFilePath(), matches.map((m) => m.node), `${identityNameOf(archCall, context)} :: ${matcher.description}`);
|
|
278
304
|
matches.forEach((match, index) => {
|
|
279
305
|
violations.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/conditions/call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAK/B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/conditions/call.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Node } from 'ts-morph';
|
|
2
|
+
import type { CatchClause } from 'ts-morph';
|
|
2
3
|
/**
|
|
3
4
|
* Result of scanning a single catch clause.
|
|
4
5
|
*/
|
|
@@ -9,7 +10,7 @@ interface SilentCatchResult {
|
|
|
9
10
|
message: string;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* Why a catch clause is silent, or `undefined` when it references the caught error.
|
|
13
14
|
*
|
|
14
15
|
* A catch clause is "silent" if:
|
|
15
16
|
* 1. It has no binding at all (`catch { ... }`) — no error to reference
|
|
@@ -27,6 +28,11 @@ interface SilentCatchResult {
|
|
|
27
28
|
* — the inner `err` usage satisfies the outer check.
|
|
28
29
|
* Both are rare in practice and arguably code smells themselves.
|
|
29
30
|
*/
|
|
31
|
+
export declare function silentCatchMessage(catchClause: CatchClause): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Find catch clauses in the body that don't reference the caught error — see
|
|
34
|
+
* `silentCatchMessage` for what counts as silent.
|
|
35
|
+
*/
|
|
30
36
|
export declare function findSilentCatches(body: Node): SilentCatchResult[];
|
|
31
37
|
export {};
|
|
32
38
|
//# sourceMappingURL=catch-analysis.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catch-analysis.d.ts","sourceRoot":"","sources":["../../src/conditions/catch-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAc,MAAM,UAAU,CAAA;AAE3C;;GAEG;AACH,UAAU,iBAAiB;IACzB,oEAAoE;IACpE,IAAI,EAAE,IAAI,CAAA;IACV,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAA;CAChB;AA8BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"catch-analysis.d.ts","sourceRoot":"","sources":["../../src/conditions/catch-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAc,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C;;GAEG;AACH,UAAU,iBAAiB;IACzB,oEAAoE;IACpE,IAAI,EAAE,IAAI,CAAA;IACV,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAA;CAChB;AA8BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAkB/E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,iBAAiB,EAAE,CAOjE"}
|
|
@@ -25,7 +25,7 @@ function getBindingNames(nameNode) {
|
|
|
25
25
|
return new Set();
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* Why a catch clause is silent, or `undefined` when it references the caught error.
|
|
29
29
|
*
|
|
30
30
|
* A catch clause is "silent" if:
|
|
31
31
|
* 1. It has no binding at all (`catch { ... }`) — no error to reference
|
|
@@ -43,35 +43,34 @@ function getBindingNames(nameNode) {
|
|
|
43
43
|
* — the inner `err` usage satisfies the outer check.
|
|
44
44
|
* Both are rare in practice and arguably code smells themselves.
|
|
45
45
|
*/
|
|
46
|
+
export function silentCatchMessage(catchClause) {
|
|
47
|
+
const varDecl = catchClause.getVariableDeclaration();
|
|
48
|
+
// catch { ... } — no binding at all, always a violation
|
|
49
|
+
if (!varDecl)
|
|
50
|
+
return 'catch block has no error binding — error is silently discarded';
|
|
51
|
+
// No binding names extracted (e.g., unusual pattern) — skip to avoid false positive
|
|
52
|
+
const bindingNames = getBindingNames(varDecl.getNameNode());
|
|
53
|
+
if (bindingNames.size === 0)
|
|
54
|
+
return undefined;
|
|
55
|
+
// Walk the catch block for Identifier nodes matching any binding name
|
|
56
|
+
const hasReference = catchClause
|
|
57
|
+
.getBlock()
|
|
58
|
+
.getDescendantsOfKind(SyntaxKind.Identifier)
|
|
59
|
+
.some((id) => bindingNames.has(id.getText()));
|
|
60
|
+
if (hasReference)
|
|
61
|
+
return undefined;
|
|
62
|
+
return `catch block binds '${varDecl.getName()}' but never references it — error is silently discarded`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Find catch clauses in the body that don't reference the caught error — see
|
|
66
|
+
* `silentCatchMessage` for what counts as silent.
|
|
67
|
+
*/
|
|
46
68
|
export function findSilentCatches(body) {
|
|
47
69
|
const results = [];
|
|
48
70
|
for (const catchClause of body.getDescendantsOfKind(SyntaxKind.CatchClause)) {
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
results.push({
|
|
53
|
-
node: catchClause,
|
|
54
|
-
message: 'catch block has no error binding — error is silently discarded',
|
|
55
|
-
});
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
// Collect the binding names to search for
|
|
59
|
-
const bindingNames = getBindingNames(varDecl.getNameNode());
|
|
60
|
-
// No binding names extracted (e.g., unusual pattern) — skip to avoid false positive
|
|
61
|
-
if (bindingNames.size === 0)
|
|
62
|
-
continue;
|
|
63
|
-
// Walk the catch block for Identifier nodes matching any binding name
|
|
64
|
-
const block = catchClause.getBlock();
|
|
65
|
-
const hasReference = block
|
|
66
|
-
.getDescendantsOfKind(SyntaxKind.Identifier)
|
|
67
|
-
.some((id) => bindingNames.has(id.getText()));
|
|
68
|
-
if (!hasReference) {
|
|
69
|
-
const varName = varDecl.getName();
|
|
70
|
-
results.push({
|
|
71
|
-
node: catchClause,
|
|
72
|
-
message: `catch block binds '${varName}' but never references it — error is silently discarded`,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
71
|
+
const message = silentCatchMessage(catchClause);
|
|
72
|
+
if (message !== undefined)
|
|
73
|
+
results.push({ node: catchClause, message });
|
|
75
74
|
}
|
|
76
75
|
return results;
|
|
77
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catch-analysis.js","sourceRoot":"","sources":["../../src/conditions/catch-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"catch-analysis.js","sourceRoot":"","sources":["../../src/conditions/catch-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAa3C;;;;;GAKG;AACH,SAAS,eAAe,CAAC,QAAc;IACrC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACtC,CAAC;IAED,IAAI,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;QAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;gBACzC,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;oBACnC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,yEAAyE;IACzE,OAAO,IAAI,GAAG,EAAU,CAAA;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAwB;IACzD,MAAM,OAAO,GAAG,WAAW,CAAC,sBAAsB,EAAE,CAAA;IAEpD,wDAAwD;IACxD,IAAI,CAAC,OAAO;QAAE,OAAO,gEAAgE,CAAA;IAErF,oFAAoF;IACpF,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IAC3D,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAE7C,sEAAsE;IACtE,MAAM,YAAY,GAAG,WAAW;SAC7B,QAAQ,EAAE;SACV,oBAAoB,CAAC,UAAU,CAAC,UAAU,CAAC;SAC3C,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAC/C,IAAI,YAAY;QAAE,OAAO,SAAS,CAAA;IAElC,OAAO,sBAAsB,OAAO,CAAC,OAAO,EAAE,yDAAyD,CAAA;AACzG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU;IAC1C,MAAM,OAAO,GAAwB,EAAE,CAAA;IACvC,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5E,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;QAC/C,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -2,11 +2,13 @@ import type { ClassDeclaration } from 'ts-morph';
|
|
|
2
2
|
import type { Condition } from '@nielspeter/eess';
|
|
3
3
|
import type { TypeMatcher } from '../helpers/type-matchers.js';
|
|
4
4
|
/**
|
|
5
|
-
* Assert that classes extend the named base class
|
|
5
|
+
* Assert that classes directly extend the named base class — written as its name, or through
|
|
6
|
+
* an aliased import, a namespace member or a mixin call.
|
|
6
7
|
*/
|
|
7
8
|
export declare function shouldExtend(className: string): Condition<ClassDeclaration>;
|
|
8
9
|
/**
|
|
9
|
-
* Assert that classes implement the named interface
|
|
10
|
+
* Assert that classes implement the named interface in their own `implements` clause — as
|
|
11
|
+
* written, or through an aliased import.
|
|
10
12
|
*/
|
|
11
13
|
export declare function shouldImplement(interfaceName: string): Condition<ClassDeclaration>;
|
|
12
14
|
/**
|
|
@@ -26,7 +28,7 @@ export declare function shouldNotHaveMethodMatching(regex: RegExp): Condition<Cl
|
|
|
26
28
|
*
|
|
27
29
|
* **Scope note:** This scans constructors, methods, AND set accessors.
|
|
28
30
|
* The function-level counterpart (`functions(p).should().acceptParameterOfType(...)`)
|
|
29
|
-
*
|
|
31
|
+
* reads a set accessor as its own function, `Class.set x` (bug 0315).
|
|
30
32
|
*/
|
|
31
33
|
export declare function acceptParameterOfType(matcher: TypeMatcher): Condition<ClassDeclaration>;
|
|
32
34
|
export declare function notAcceptParameterOfType(matcher: TypeMatcher): Condition<ClassDeclaration>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.d.ts","sourceRoot":"","sources":["../../src/conditions/class.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,UAAU,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAInE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"class.d.ts","sourceRoot":"","sources":["../../src/conditions/class.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,UAAU,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAInE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAG9D;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAM3E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAMlF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAM/E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAYtF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAyBvF;AAkDD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAW1F"}
|
package/dist/conditions/class.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { elementCondition } from './helpers.js';
|
|
2
2
|
import { createViolation, getElementName } from '../core/violation.js';
|
|
3
|
+
import { extendsByName, implementsByName } from '../helpers/heritage.js';
|
|
3
4
|
/**
|
|
4
|
-
* Assert that classes extend the named base class
|
|
5
|
+
* Assert that classes directly extend the named base class — written as its name, or through
|
|
6
|
+
* an aliased import, a namespace member or a mixin call.
|
|
5
7
|
*/
|
|
6
8
|
export function shouldExtend(className) {
|
|
7
|
-
return elementCondition(`extend "${className}"`, (cls) => cls
|
|
9
|
+
return elementCondition(`extend "${className}"`, (cls) => extendsByName(cls, className), (cls) => `${getElementName(cls)} does not extend "${className}"`);
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
|
-
* Assert that classes implement the named interface
|
|
12
|
+
* Assert that classes implement the named interface in their own `implements` clause — as
|
|
13
|
+
* written, or through an aliased import.
|
|
11
14
|
*/
|
|
12
15
|
export function shouldImplement(interfaceName) {
|
|
13
|
-
return elementCondition(`implement "${interfaceName}"`, (cls) => cls
|
|
16
|
+
return elementCondition(`implement "${interfaceName}"`, (cls) => implementsByName(cls, interfaceName), (cls) => `${getElementName(cls)} does not implement "${interfaceName}"`);
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Assert that classes have a method with the given name.
|
|
@@ -39,7 +42,7 @@ export function shouldNotHaveMethodMatching(regex) {
|
|
|
39
42
|
*
|
|
40
43
|
* **Scope note:** This scans constructors, methods, AND set accessors.
|
|
41
44
|
* The function-level counterpart (`functions(p).should().acceptParameterOfType(...)`)
|
|
42
|
-
*
|
|
45
|
+
* reads a set accessor as its own function, `Class.set x` (bug 0315).
|
|
43
46
|
*/
|
|
44
47
|
export function acceptParameterOfType(matcher) {
|
|
45
48
|
return {
|
|
@@ -70,7 +73,7 @@ export function acceptParameterOfType(matcher) {
|
|
|
70
73
|
*
|
|
71
74
|
* **Scope note:** This scans constructors, methods, AND set accessors.
|
|
72
75
|
* The function-level counterpart (`functions(p).should().notAcceptParameterOfType(...)`)
|
|
73
|
-
*
|
|
76
|
+
* reads a set accessor as its own function, `Class.set x` (bug 0315).
|
|
74
77
|
*/
|
|
75
78
|
/**
|
|
76
79
|
* Scan parameters of class members (constructors, methods, set accessors) for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../src/conditions/class.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../src/conditions/class.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAEtE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAExE;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,gBAAgB,CACrB,WAAW,SAAS,GAAG,EACvB,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,EACtC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,qBAAqB,SAAS,GAAG,CACjE,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,aAAqB;IACnD,OAAO,gBAAgB,CACrB,cAAc,aAAa,GAAG,EAC9B,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,EAC7C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,wBAAwB,aAAa,GAAG,CACxE,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,gBAAgB,CACrB,sBAAsB,IAAI,GAAG,EAC7B,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,SAAS,EAC1C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,0BAA0B,IAAI,GAAG,CACjE,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACvD,OAAO,gBAAgB,CACrB,6BAA6B,MAAM,CAAC,KAAK,CAAC,EAAE,EAC5C,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAC/D,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,QAAQ,GAAG,GAAG;aACjB,UAAU,EAAE;aACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QAC1B,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IAC/F,CAAC,CACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAoB;IACxD,OAAO;QACL,WAAW,EAAE,mCAAmC;QAChD,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,SAAS,GAAG;oBAChB,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;oBAC1D,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;oBACrD,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;iBAC3D,CAAA;gBACD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;gBAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,UAAU,CAAC,IAAI,CACb,eAAe,CACb,GAAG,EACH,GAAG,cAAc,CAAC,GAAG,CAAC,sCAAsC,EAC5D,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,GAAqB,EACrB,WAAwB,EACxB,OAAyB;IAEzB,MAAM,UAAU,GAAoB,EAAE,CAAA;IACtC,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IAErC,MAAM,OAAO,GAAkE;QAC7E,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAC/F,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACxF,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;KAC9F,CAAA;IAED,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBACjC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,EAAE,CAAA;gBACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAA;gBAC1C,UAAU,CAAC,IAAI,CACb,eAAe,CACb,GAAG,EACH,GAAG,SAAS,IAAI,UAAU,eAAe,SAAS,eAAe,QAAQ,GAAG,EAC5E,OAAO,CACR,CACF,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO;QACL,WAAW,EAAE,uCAAuC;QACpD,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,UAAU,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;YAClE,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -34,8 +34,8 @@ export declare function haveNameMatching(pattern: RegExp): Condition<ArchFunctio
|
|
|
34
34
|
* Reports one violation per function that has no matching parameter.
|
|
35
35
|
*
|
|
36
36
|
* **Scope note:** This operates on the function's own parameter list only.
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
* A set accessor is a function of its own, `Class.set x`, since bug 0315; the class-level
|
|
38
|
+
* counterpart scans the whole class at once.
|
|
39
39
|
*/
|
|
40
40
|
export declare function acceptParameterOfType(matcher: TypeMatcher): Condition<ArchFunction>;
|
|
41
41
|
/**
|
|
@@ -46,8 +46,8 @@ export declare function acceptParameterOfType(matcher: TypeMatcher): Condition<A
|
|
|
46
46
|
* with actionable messages including the parameter name and type.
|
|
47
47
|
*
|
|
48
48
|
* **Scope note:** This operates on the function's own parameter list only.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* A set accessor is a function of its own, `Class.set x`, since bug 0315; the class-level
|
|
50
|
+
* counterpart scans the whole class at once.
|
|
51
51
|
*/
|
|
52
52
|
export declare function notAcceptParameterOfType(matcher: TypeMatcher): Condition<ArchFunction>;
|
|
53
53
|
/**
|
|
@@ -89,8 +89,8 @@ export function haveNameMatching(pattern) {
|
|
|
89
89
|
* Reports one violation per function that has no matching parameter.
|
|
90
90
|
*
|
|
91
91
|
* **Scope note:** This operates on the function's own parameter list only.
|
|
92
|
-
*
|
|
93
|
-
*
|
|
92
|
+
* A set accessor is a function of its own, `Class.set x`, since bug 0315; the class-level
|
|
93
|
+
* counterpart scans the whole class at once.
|
|
94
94
|
*/
|
|
95
95
|
export function acceptParameterOfType(matcher) {
|
|
96
96
|
return functionCondition('accept parameter of matching type', (fn) => fn.getParameters().some((p) => matcher(p.getType())), (fn) => `${fn.getName() ?? '<anonymous>'} has no parameter with matching type`);
|
|
@@ -103,8 +103,8 @@ export function acceptParameterOfType(matcher) {
|
|
|
103
103
|
* with actionable messages including the parameter name and type.
|
|
104
104
|
*
|
|
105
105
|
* **Scope note:** This operates on the function's own parameter list only.
|
|
106
|
-
*
|
|
107
|
-
*
|
|
106
|
+
* A set accessor is a function of its own, `Class.set x`, since bug 0315; the class-level
|
|
107
|
+
* counterpart scans the whole class at once.
|
|
108
108
|
*/
|
|
109
109
|
export function notAcceptParameterOfType(matcher) {
|
|
110
110
|
return {
|
|
@@ -181,7 +181,7 @@ export function applyFilters(violations, ctx) {
|
|
|
181
181
|
// pattern that silences NOTHING (fail-closed — the finding still fires, CI is
|
|
182
182
|
// still red), while this warns about a pattern that silences MULTIPLE real
|
|
183
183
|
// findings and every future one on the same edges (fail-open — a green
|
|
184
|
-
// `check()`, one stderr line). ADR-
|
|
184
|
+
// `check()`, one stderr line). ADR-009 states the primary consumer does not
|
|
185
185
|
// read warnings. Kept advisory here, matching plan 0104's own review
|
|
186
186
|
// resolution — but the asymmetry is real and worth re-litigating if this
|
|
187
187
|
// loophole is measured firing in practice, not settled by the precedent
|
|
@@ -38,5 +38,8 @@ export interface ObjectLiteralFunction {
|
|
|
38
38
|
* Only descends into nested object-literal property values, never into function
|
|
39
39
|
* bodies. Returns `[]` when `node` is not an object literal.
|
|
40
40
|
*/
|
|
41
|
-
export declare function collectObjectLiteralFunctions(node: Node,
|
|
41
|
+
export declare function collectObjectLiteralFunctions(node: Node, options?: {
|
|
42
|
+
includeAccessors?: boolean;
|
|
43
|
+
maxDepth?: number;
|
|
44
|
+
}): ObjectLiteralFunction[];
|
|
42
45
|
//# sourceMappingURL=object-literal-functions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-literal-functions.d.ts","sourceRoot":"","sources":["../../src/core/object-literal-functions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"object-literal-functions.d.ts","sourceRoot":"","sources":["../../src/core/object-literal-functions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAI/B;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,sFAAsF;IACtF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC;AAKD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,qBAAqB,EAAE,CAWzB"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* both `models → core` and `helpers → core` are permitted directions.
|
|
19
19
|
*/
|
|
20
20
|
import { Node } from 'ts-morph';
|
|
21
|
+
import { throughWrappers } from './through-wrappers.js';
|
|
21
22
|
/** Default recursion depth into nested object literals (matches the callback path). */
|
|
22
23
|
const MAX_OBJECT_LITERAL_DEPTH = 3;
|
|
23
24
|
/**
|
|
@@ -30,12 +31,12 @@ const MAX_OBJECT_LITERAL_DEPTH = 3;
|
|
|
30
31
|
* Only descends into nested object-literal property values, never into function
|
|
31
32
|
* bodies. Returns `[]` when `node` is not an object literal.
|
|
32
33
|
*/
|
|
33
|
-
export function collectObjectLiteralFunctions(node,
|
|
34
|
+
export function collectObjectLiteralFunctions(node, options = {}) {
|
|
34
35
|
const out = [];
|
|
35
|
-
walk(node, [], 0, maxDepth, out);
|
|
36
|
+
walk(node, [], 0, options.maxDepth ?? MAX_OBJECT_LITERAL_DEPTH, out, options.includeAccessors ?? false);
|
|
36
37
|
return out;
|
|
37
38
|
}
|
|
38
|
-
function walk(node, keyPath, depth, maxDepth, out) {
|
|
39
|
+
function walk(node, keyPath, depth, maxDepth, out, includeAccessors) {
|
|
39
40
|
if (!Node.isObjectLiteralExpression(node))
|
|
40
41
|
return;
|
|
41
42
|
if (depth >= maxDepth)
|
|
@@ -46,9 +47,30 @@ function walk(node, keyPath, depth, maxDepth, out) {
|
|
|
46
47
|
out.push({ node: prop, keyPath: [...keyPath, keyOf(prop)] });
|
|
47
48
|
continue;
|
|
48
49
|
}
|
|
50
|
+
// An accessor is a function the object defines — the object-literal counterpart of the class
|
|
51
|
+
// accessors bug 0315 collected — so the FUNCTION collection reads it (bug 0321). The callback
|
|
52
|
+
// path does not: whether a rule about callbacks should read a function that runs on access
|
|
53
|
+
// rather than on call is an open ruling, recorded as bug 0331. Hence the option: one traversal,
|
|
54
|
+
// and the difference declared at the call site rather than discovered.
|
|
55
|
+
if (Node.isGetAccessorDeclaration(prop) || Node.isSetAccessorDeclaration(prop)) {
|
|
56
|
+
if (includeAccessors) {
|
|
57
|
+
out.push({
|
|
58
|
+
node: prop,
|
|
59
|
+
keyPath: [
|
|
60
|
+
...keyPath,
|
|
61
|
+
`${Node.isGetAccessorDeclaration(prop) ? 'get' : 'set'} ${prop.getName()}`,
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
49
67
|
if (!Node.isPropertyAssignment(prop))
|
|
50
68
|
continue;
|
|
51
|
-
|
|
69
|
+
// Read through parentheses, `as`, `<T>`, `satisfies` and `!`: `{ handler: (() => …) as H }`
|
|
70
|
+
// holds the same function as `{ handler: () => … }`, and the callback extractor unwraps the
|
|
71
|
+
// ARGUMENT with the same list. Measured with the two copies apart: the wrapped property value
|
|
72
|
+
// was read by neither reader (the enforcement review of bug 0324).
|
|
73
|
+
const init = throughWrappers(prop.getInitializer());
|
|
52
74
|
if (!init)
|
|
53
75
|
continue;
|
|
54
76
|
const key = keyOf(prop);
|
|
@@ -59,7 +81,7 @@ function walk(node, keyPath, depth, maxDepth, out) {
|
|
|
59
81
|
}
|
|
60
82
|
// Nested object literal — recurse (depth-limited).
|
|
61
83
|
if (Node.isObjectLiteralExpression(init)) {
|
|
62
|
-
walk(init, [...keyPath, key], depth + 1, maxDepth, out);
|
|
84
|
+
walk(init, [...keyPath, key], depth + 1, maxDepth, out, includeAccessors);
|
|
63
85
|
}
|
|
64
86
|
}
|
|
65
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-literal-functions.js","sourceRoot":"","sources":["../../src/core/object-literal-functions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"object-literal-functions.js","sourceRoot":"","sources":["../../src/core/object-literal-functions.ts"],"names":[],"mappings":"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"}
|